home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / binutils.252 / gas / config / obj-vms.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-19  |  138.4 KB  |  5,641 lines

  1. /* vms.c -- Write out a VAX/VMS object file
  2.    Copyright (C) 1987, 1988, 1992, 1994 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* Written by David L. Kashtan */
  21. /* Modified by Eric Youngdale to write VMS debug records for program
  22.    variables */
  23. #include "as.h"
  24. #include "config.h"
  25. #include "subsegs.h"
  26. #include "obstack.h"
  27.  
  28. /* What we do if there is a goof. */
  29. #define error as_fatal
  30.  
  31. #ifdef VMS            /* These are of no use if we are cross assembling. */
  32. #include <fab.h>        /* Define File Access Block      */
  33. #include <nam.h>        /* Define NAM Block          */
  34. #include <xab.h>        /* Define XAB - all different types*/
  35. #endif
  36. /*
  37.  *    Version string of the compiler that produced the code we are
  38.  *    assembling.  (And this assembler, if we do not have compiler info.)
  39.  */
  40. char *compiler_version_string;
  41.  
  42. extern int flag_hash_long_names;    /* -+ */
  43. extern int flag_one;            /* -1 */
  44. extern int flag_show_after_trunc;    /* -H */
  45. extern int flag_no_hash_mixed_case;    /* -h NUM */
  46.  
  47. /* Flag that determines how we map names.  This takes several values, and
  48.  * is set with the -h switch.  A value of zero implies names should be 
  49.  * upper case, and the presence of the -h switch inhibits the case hack.
  50.  * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
  51.  * A value of 2 (set with -h2) implies names should be
  52.  * all lower case, with no case hack.  A value of 3 (set with -h3) implies
  53.  * that case should be preserved.  */
  54.  
  55. /* If the -+ switch is given, then the hash is appended to any name that is
  56.  * longer than 31 characters, irregardless of the setting of the -h switch.
  57.  */
  58.  
  59. char vms_name_mapping = 0;
  60.  
  61. extern char *myname;
  62. static symbolS *Entry_Point_Symbol = 0;    /* Pointer to "_main" */
  63.  
  64. /*
  65.  *    We augment the "gas" symbol structure with this
  66.  */
  67. struct VMS_Symbol
  68. {
  69.   struct VMS_Symbol *Next;
  70.   struct symbol *Symbol;
  71.   int Size;
  72.   int Psect_Index;
  73.   int Psect_Offset;
  74. };
  75. struct VMS_Symbol *VMS_Symbols = 0;
  76.  
  77. /* We need this to keep track of the various input files, so that we can
  78.  * give the debugger the correct source line.
  79.  */
  80.  
  81. struct input_file
  82. {
  83.   struct input_file *next;
  84.   struct input_file *same_file_fpnt;
  85.   int file_number;
  86.   int max_line;
  87.   int min_line;
  88.   int offset;
  89.   char flag;
  90.   char *name;
  91.   symbolS *spnt;
  92. };
  93.  
  94. static struct input_file *file_root = (struct input_file *) NULL;
  95.  
  96.  
  97. static struct input_file *find_file PARAMS ((symbolS *));
  98.  
  99. /*
  100.  * This enum is used to keep track of the various types of variables that
  101.  * may be present.
  102.  */
  103.  
  104. enum advanced_type
  105. {
  106.   BASIC, POINTER, ARRAY, ENUM, STRUCT, UNION, FUNCTION, VOID, ALIAS, UNKNOWN
  107. };
  108.  
  109. /*
  110.  * This structure contains the information from the stabs directives, and the
  111.  * information is filled in by VMS_typedef_parse.  Everything that is needed
  112.  * to generate the debugging record for a given symbol is present here.
  113.  * This could be done more efficiently, using nested struct/unions, but for now
  114.  * I am happy that it works.
  115.  */
  116. struct VMS_DBG_Symbol
  117. {
  118.   struct VMS_DBG_Symbol *next;
  119.   /* description of what this is */
  120.   enum advanced_type advanced;
  121.   /* this record is for this type */
  122.   int dbx_type;
  123.   /* For advanced types this is the type referred to.  I.e., the type
  124.      a pointer points to, or the type of object that makes up an
  125.      array.  */
  126.   int type2;
  127.   /* Use this type when generating a variable def */
  128.   int VMS_type;
  129.   /* used for arrays - this will be present for all */
  130.   int index_min;
  131.   /* entries, but will be meaningless for non-arrays */
  132.   int index_max;
  133.   /* Size in bytes of the data type.  For an array, this is the size
  134.      of one element in the array */
  135.   int data_size;
  136.   /* Number of the structure/union/enum - used for ref */
  137.   int struc_numb;
  138. };
  139.  
  140. struct VMS_DBG_Symbol *VMS_Symbol_type_list;
  141.  
  142. /*
  143.  * We need this structure to keep track of forward references to
  144.  * struct/union/enum that have not been defined yet.  When they are ultimately
  145.  * defined, then we can go back and generate the TIR commands to make a back
  146.  * reference.
  147.  */
  148.  
  149. struct forward_ref
  150. {
  151.   struct forward_ref *next;
  152.   int dbx_type;
  153.   int struc_numb;
  154.   char resolved;
  155. };
  156.  
  157. struct forward_ref *f_ref_root =
  158. {(struct forward_ref *) NULL};
  159.  
  160. /*
  161.  * This routine is used to compare the names of certain types to various
  162.  * fixed types that are known by the debugger.
  163.  */
  164. #define type_check(x)  !strcmp( symbol_name , x )
  165.  
  166. /*
  167.  * This variable is used to keep track of the name of the symbol we are
  168.  * working on while we are parsing the stabs directives.
  169.  */
  170. static char *symbol_name;
  171.  
  172. /* We use this counter to assign numbers to all of the structures, unions
  173.  * and enums that we define.  When we actually declare a variable to the
  174.  * debugger, we can simply do it by number, rather than describing the
  175.  * whole thing each time.
  176.  */
  177.  
  178. static structure_count = 0;
  179.  
  180. /* This variable is used to indicate that we are making the last attempt to
  181.    parse the stabs, and that we should define as much as we can, and ignore 
  182.    the rest */
  183.  
  184. static int final_pass;
  185.  
  186. /* This variable is used to keep track of the current structure number
  187.  * for a given variable.  If this is < 0, that means that the structure
  188.  * has not yet been defined to the debugger.  This is still cool, since
  189.  * the VMS object language has ways of fixing things up after the fact,
  190.  * so we just make a note of this, and generate fixups at the end.
  191.  */
  192. static int struct_number;
  193.  
  194. /* This is used to distinguish between D_float and G_float for telling
  195.    the debugger about doubles.  gcc outputs the same .stabs regardless
  196.    of whether -mg is used to select alternate doubles.  */
  197.  
  198. static int vax_g_doubles = 0;
  199.  
  200.  
  201. /*
  202.  * Variable descriptors are used tell the debugger the data types of certain
  203.  * more complicated variables (basically anything involving a structure,
  204.  * union, enum, array or pointer).  Some non-pointer variables of the
  205.  * basic types that the debugger knows about do not require a variable
  206.  * descriptor.
  207.  *
  208.  * Since it is impossible to have a variable descriptor longer than 128
  209.  * bytes by virtue of the way that the VMS object language is set up,
  210.  * it makes not sense to make the arrays any longer than this, or worrying
  211.  * about dynamic sizing of the array.
  212.  *
  213.  * These are the arrays and counters that we use to build a variable
  214.  * descriptor.
  215.  */
  216.  
  217. #define MAX_DEBUG_RECORD 128
  218. static char Local[MAX_DEBUG_RECORD];    /* buffer for variable descriptor */
  219. static char Asuffix[MAX_DEBUG_RECORD];    /* buffer for array descriptor */
  220. static int Lpnt;        /* index into Local */
  221. static int Apoint;        /* index into Asuffix */
  222. static char overflow;        /* flag to indicate we have written too much*/
  223. static int total_len;        /* used to calculate the total length of variable
  224.                 descriptor plus array descriptor - used for len byte*/
  225.  
  226. /* Flag if we have told user about finding global constants in the text
  227.    section. */
  228. static gave_compiler_message = 0;
  229.  
  230. /* A pointer to the current routine that we are working on.  */
  231.  
  232. static symbolS *Current_Routine;
  233.  
  234. /* The psect number for $code a.k.a. the text section. */
  235.  
  236. static int Text_Psect;
  237.  
  238.  
  239. /*
  240.  *    Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
  241.  */
  242. static int VMS_Object_File_FD;    /* File Descriptor for object file */
  243. static char Object_Record_Buffer[512];    /* Buffer for object file records  */
  244. static int Object_Record_Offset;/* Offset to end of data       */
  245. static int Current_Object_Record_Type;    /* Type of record in above       */
  246.  
  247. /*
  248.  *    Macros for moving data around.  Must work on big-endian systems.
  249.  */
  250. #ifdef VMS  /* These are more efficient for VMS->VMS systems */
  251. #define COPY_LONG(dest,val) {*(long *) dest = val; }
  252. #define COPY_SHORT(dest,val) {*(short *) dest = val; }
  253. #else
  254. #define    COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
  255. #define    COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
  256. #endif
  257. /*
  258.  *    Macros for placing data into the object record buffer
  259.  */
  260.  
  261. #define    PUT_LONG(val) \
  262. { md_number_to_chars(Object_Record_Buffer + \
  263.              Object_Record_Offset, val, 4); \
  264.              Object_Record_Offset += 4; }
  265.  
  266. #define    PUT_SHORT(val) \
  267. { md_number_to_chars(Object_Record_Buffer + \
  268.              Object_Record_Offset, val, 2); \
  269.              Object_Record_Offset += 2; }
  270.  
  271. #define    PUT_CHAR(val)    Object_Record_Buffer[Object_Record_Offset++] = val
  272.  
  273. #define    PUT_COUNTED_STRING(cp) {\
  274.             register char *p = cp; \
  275.             PUT_CHAR(strlen(p)); \
  276.             while (*p) PUT_CHAR(*p++);}
  277.  
  278. /*
  279.  *    Macro for determining if a Name has psect attributes attached
  280.  *    to it.
  281.  */
  282. #define    PSECT_ATTRIBUTES_STRING        "$$PsectAttributes_"
  283. #define    PSECT_ATTRIBUTES_STRING_LENGTH    18
  284.  
  285. #define    HAS_PSECT_ATTRIBUTES(Name) \
  286.         (strncmp((Name[0] == '_' ? Name + 1 : Name), \
  287.          PSECT_ATTRIBUTES_STRING, \
  288.          PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
  289.  
  290.  
  291.  /* in: segT   out: N_TYPE bits */
  292. const short seg_N_TYPE[] =
  293. {
  294.   N_ABS,
  295.   N_TEXT,
  296.   N_DATA,
  297.   N_BSS,
  298.   N_UNDF,            /* unknown */
  299.   N_UNDF,            /* error */
  300.   N_UNDF,            /* expression */
  301.   N_UNDF,            /* debug */
  302.   N_UNDF,            /* ntv */
  303.   N_UNDF,            /* ptv */
  304.   N_REGISTER,            /* register */
  305. };
  306.  
  307. const segT N_TYPE_seg[N_TYPE + 2] =
  308. {                /* N_TYPE == 0x1E = 32-2 */
  309.   SEG_UNKNOWN,            /* N_UNDF == 0 */
  310.   SEG_GOOF,
  311.   SEG_ABSOLUTE,            /* N_ABS == 2 */
  312.   SEG_GOOF,
  313.   SEG_TEXT,            /* N_TEXT == 4 */
  314.   SEG_GOOF,
  315.   SEG_DATA,            /* N_DATA == 6 */
  316.   SEG_GOOF,
  317.   SEG_BSS,            /* N_BSS == 8 */
  318.   SEG_GOOF,
  319.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
  320.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
  321.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
  322.   SEG_REGISTER,            /* dummy N_REGISTER for regs = 30 */
  323.   SEG_GOOF,
  324. };
  325.  
  326.  
  327. /* The following code defines the special types of pseudo-ops that we
  328.  *  use with VMS.
  329.  */
  330.  
  331. char const_flag = IN_DEFAULT_SECTION;
  332.  
  333. void
  334. s_const ()
  335. {
  336.   register int temp;
  337.  
  338.   temp = get_absolute_expression ();
  339.   subseg_set (SEG_DATA, (subsegT) temp);
  340.   const_flag = 1;
  341.   demand_empty_rest_of_line ();
  342. }
  343.  
  344. const pseudo_typeS obj_pseudo_table[] =
  345. {
  346.   {"const", s_const, 0},
  347.   {0, 0, 0},
  348. };                /* obj_pseudo_table */
  349.  
  350. int
  351. vms_resolve_symbol_redef (sym)
  352.      symbolS *sym;
  353. {
  354.   /*
  355.    *    If the new symbol is .comm AND it has a size of zero,
  356.    *    we ignore it (i.e. the old symbol overrides it)
  357.    */
  358.   if ((SEGMENT_TO_SYMBOL_TYPE ((int) now_seg) == (N_UNDF | N_EXT)) &&
  359.       ((obstack_next_free (&frags) - frag_now->fr_literal) == 0))
  360.     {
  361.       as_warn ("compiler emitted zero-size common symbol `%s' already defined",
  362.            S_GET_NAME (sym));
  363.       return 1;
  364.     }
  365.   /*
  366.    *    If the old symbol is .comm and it has a size of zero,
  367.    *    we override it with the new symbol value.
  368.    */
  369.   if (S_IS_EXTERNAL(sym) &&  S_IS_DEFINED(sym)
  370.       && (S_GET_VALUE(sym) == 0))
  371.     {
  372.       as_warn ("compiler redefined zero-size common symbol `%s'",
  373.            S_GET_NAME (sym));
  374.       sym->sy_frag  = frag_now;
  375.       S_SET_OTHER(sym, const_flag);
  376.       S_SET_VALUE(sym, obstack_next_free(& frags) - frag_now->fr_literal);
  377.       /* Keep N_EXT bit.  */
  378.       sym->sy_symbol.n_type |= SEGMENT_TO_SYMBOL_TYPE((int) now_seg);
  379.       return 1;
  380.     }
  381.  
  382.   return 0;
  383. }
  384.  
  385. /* `tc_frob_label' handler for colon(symbols.c), used to examine the
  386.    dummy label(s) gcc inserts at the beginning of each file it generates.
  387.    gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.6) puts "gcc2_compiled."
  388.    and "__gnu_language_<name>" and possibly "__vax_<type>_doubles".  */
  389.  
  390. void
  391. vms_check_for_special_label (symbolP) 
  392. symbolS *symbolP;
  393. {
  394.   /* Special labels only occur prior to explicit section directives.  */
  395.   if ((const_flag & IN_DEFAULT_SECTION) != 0)
  396.     {
  397.       char *sym_name = S_GET_NAME(symbolP);
  398.  
  399.       if (*sym_name == '_')
  400.     ++sym_name;
  401.  
  402.       if (!strcmp (sym_name, "__vax_g_doubles"))
  403.     vax_g_doubles = 1;
  404. #if 0    /* not necessary */
  405.       else if (!strcmp (sym_name, "__vax_d_doubles"))
  406.     vax_g_doubles = 0;
  407. #endif
  408. #if 0    /* these are potential alternatives to tc-vax.c's md_parse_options() */
  409.       else if (!strcmp (sym_name, "gcc_compiled."))
  410.     flag_one = 1;
  411.       else if (!strcmp (sym_name, "__gnu_language_cplusplus"))
  412.     flag_hash_long_names = 1;
  413. #endif
  414.     }
  415.   return;
  416. }
  417.  
  418. void 
  419. obj_read_begin_hook ()
  420. {
  421. }
  422.  
  423. void 
  424. obj_crawl_symbol_chain (headers)
  425.      object_headers *headers;
  426. {
  427.   symbolS *symbolP;
  428.   symbolS **symbolPP;
  429.   int symbol_number = 0;
  430.  
  431.   {                /* crawl symbol table */
  432.     register int symbol_number = 0;
  433.  
  434.     {
  435.       symbolPP = &symbol_rootP;    /* -> last symbol chain link. */
  436.       while ((symbolP = *symbolPP) != NULL)
  437.     {
  438.       resolve_symbol_value (symbolP);
  439.  
  440.       /* OK, here is how we decide which symbols go out into the
  441.          brave new symtab.  Symbols that do are:
  442.         
  443.          * symbols with no name (stabd's?)
  444.          * symbols with debug info in their N_TYPE
  445.         
  446.          Symbols that don't are:
  447.          * symbols that are registers
  448.          * symbols with \1 as their 3rd character (numeric labels)
  449.          * "local labels" as defined by S_LOCAL_NAME(name)
  450.          if the -L switch was passed to gas.
  451.         
  452.          All other symbols are output.  We complain if a deleted
  453.          symbol was marked external.  */
  454.  
  455.  
  456.       if (!S_IS_REGISTER (symbolP))
  457.         {
  458.           symbolP->sy_name_offset = 0;
  459.           symbolPP = &(symbol_next (symbolP));
  460.         }
  461.       else
  462.         {
  463.           if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
  464.         {
  465.           as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP));
  466.         }        /* oops. */
  467.  
  468.         }            /* if this symbol should be in the output */
  469.     }            /* for each symbol */
  470.     }
  471.     H_SET_STRING_SIZE (headers, string_byte_count);
  472.     H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
  473.   }                /* crawl symbol table */
  474.  
  475. }                /* obj_crawl_symbol_chain() */
  476.  
  477.  
  478.  /****** VMS OBJECT FILE HACKING ROUTINES *******/
  479.  
  480.  
  481. /*
  482.  *    Create the VMS object file
  483.  */
  484. static
  485. Create_VMS_Object_File ()
  486. {
  487. #if    defined(eunice) || !defined(VMS)
  488.   VMS_Object_File_FD = creat (out_file_name, 0777, "var");
  489. #else    /* eunice */
  490.   VMS_Object_File_FD = creat (out_file_name, 0, "rfm=var", 
  491.                  "mbc=16", "deq=64", "fop=tef", "shr=nil");
  492. #endif    /* eunice */
  493.   /*
  494.    *    Deal with errors
  495.    */
  496.   if (VMS_Object_File_FD < 0)
  497.     {
  498.       char Error_Line[256];
  499.  
  500.       sprintf (Error_Line, "Couldn't create VMS object file \"%s\"",
  501.            out_file_name);
  502.       error (Error_Line);
  503.     }
  504.   /*
  505.    *    Initialize object file hacking variables
  506.    */
  507.   Object_Record_Offset = 0;
  508.   Current_Object_Record_Type = -1;
  509. }
  510.  
  511.  
  512. /*
  513.  *    Flush the object record buffer to the object file
  514.  */
  515. static
  516. Flush_VMS_Object_Record_Buffer ()
  517. {
  518.   int i;
  519.   short int zero;
  520.   int RecLen;
  521.   /*
  522.    *    If the buffer is empty, we are done
  523.    */
  524.   if (Object_Record_Offset == 0)
  525.     return;
  526.   /*
  527.    *    Write the data to the file
  528.    */
  529. #ifndef VMS            /* For cross-assembly purposes. */
  530.   md_number_to_chars((char *) &RecLen, Object_Record_Offset, 2);
  531.   i = write (VMS_Object_File_FD, &RecLen, 2);
  532. #endif /* not VMS */
  533.   i = write (VMS_Object_File_FD,
  534.          Object_Record_Buffer,
  535.          Object_Record_Offset);
  536.   if (i != Object_Record_Offset)
  537.     error ("I/O error writing VMS object file");
  538. #ifndef VMS            /* When cross-assembling, we need to pad the record to an even
  539.                         number of bytes. */
  540.   /* pad it if needed */
  541.   zero = 0;
  542.   if (Object_Record_Offset & 1 != 0)
  543.     write (VMS_Object_File_FD, &zero, 1);
  544. #endif /* not VMS */
  545.   /*
  546.    *    The buffer is now empty
  547.    */
  548.   Object_Record_Offset = 0;
  549. }
  550.  
  551.  
  552. /*
  553.  *    Declare a particular type of object file record
  554.  */
  555. static
  556. Set_VMS_Object_File_Record (Type)
  557.      int Type;
  558. {
  559.   /*
  560.    *    If the type matches, we are done
  561.    */
  562.   if (Type == Current_Object_Record_Type)
  563.     return;
  564.   /*
  565.    *    Otherwise: flush the buffer
  566.    */
  567.   Flush_VMS_Object_Record_Buffer ();
  568.   /*
  569.    *    Set the new type
  570.    */
  571.   Current_Object_Record_Type = Type;
  572. }
  573.  
  574.  
  575.  
  576. /*
  577.  *    Close the VMS Object file
  578.  */
  579. static
  580. Close_VMS_Object_File ()
  581. {
  582.   short int m_one = -1;
  583.   /* @@ This should not be here!!  The same would presumably be needed
  584.      if we were writing vax-bsd a.out files on a vms system.  Put it
  585.      someplace else!  */
  586. #ifndef VMS            /* For cross-assembly purposes. */
  587. /* Write a 0xffff into the file, which means "End of File" */
  588.   write (VMS_Object_File_FD, &m_one, 2);
  589. #endif /* not VMS */
  590.   close (VMS_Object_File_FD);
  591. }
  592.  
  593.  
  594. /*
  595.  *    Store immediate data in current Psect
  596.  */
  597. static
  598. VMS_Store_Immediate_Data (Pointer, Size, Record_Type)
  599.      CONST char *Pointer;
  600.      int Size;
  601.      int Record_Type;
  602. {
  603.   register int i;
  604.  
  605.   /*
  606.    *    We are writing a "Record_Type" record
  607.    */
  608.   Set_VMS_Object_File_Record (Record_Type);
  609.   /*
  610.    *    We can only store 128 bytes at a time
  611.    */
  612.   while (Size > 0)
  613.     {
  614.       /*
  615.        *    Store a maximum of 128 bytes
  616.        */
  617.       i = (Size > 128) ? 128 : Size;
  618.       Size -= i;
  619.       /*
  620.        *    If we cannot accommodate this record, flush the
  621.        *    buffer.
  622.        */
  623.       if ((Object_Record_Offset + i + 1) >=
  624.       sizeof (Object_Record_Buffer))
  625.     Flush_VMS_Object_Record_Buffer ();
  626.       /*
  627.        *    If the buffer is empty we must insert record type
  628.        */
  629.       if (Object_Record_Offset == 0)
  630.     PUT_CHAR (Record_Type);
  631.       /*
  632.        *    Store the count
  633.        */
  634.       PUT_CHAR (-i & 0xff);
  635.       /*
  636.        *    Store the data
  637.        */
  638.       while (--i >= 0)
  639.     PUT_CHAR (*Pointer++);
  640.       /*
  641.        *    Flush the buffer if it is more than 75% full
  642.        */
  643.       if (Object_Record_Offset >
  644.       (sizeof (Object_Record_Buffer) * 3 / 4))
  645.     Flush_VMS_Object_Record_Buffer ();
  646.     }
  647. }
  648.  
  649. /*
  650.  *    Make a data reference
  651.  */
  652. static
  653. VMS_Set_Data (Psect_Index, Offset, Record_Type, Force)
  654.      int Psect_Index;
  655.      int Offset;
  656.      int Record_Type;
  657.      int Force;
  658. {
  659.   /*
  660.    *    We are writing a "Record_Type" record
  661.    */
  662.   Set_VMS_Object_File_Record (Record_Type);
  663.   /*
  664.    *    If the buffer is empty we must insert the record type
  665.    */
  666.   if (Object_Record_Offset == 0)
  667.     PUT_CHAR (Record_Type);
  668.   /*
  669.    *    Stack the Psect base + Longword Offset
  670.    */
  671.   if (Force == 1)
  672.     {
  673.       if (Psect_Index > 127)
  674.     {
  675.       PUT_CHAR (TIR_S_C_STA_WPL);
  676.       PUT_SHORT (Psect_Index);
  677.       PUT_LONG (Offset);
  678.     }
  679.       else
  680.     {
  681.       PUT_CHAR (TIR_S_C_STA_PL);
  682.       PUT_CHAR (Psect_Index);
  683.       PUT_LONG (Offset);
  684.     }
  685.     }
  686.   else
  687.     {
  688.       if (Offset > 32767)
  689.     {
  690.       PUT_CHAR (TIR_S_C_STA_WPL);
  691.       PUT_SHORT (Psect_Index);
  692.       PUT_LONG (Offset);
  693.     }
  694.       else if (Offset > 127)
  695.     {
  696.       PUT_CHAR (TIR_S_C_STA_WPW);
  697.       PUT_SHORT (Psect_Index);
  698.       PUT_SHORT (Offset);
  699.     }
  700.       else
  701.     {
  702.       PUT_CHAR (TIR_S_C_STA_WPB);
  703.       PUT_SHORT (Psect_Index);
  704.       PUT_CHAR (Offset);
  705.     }
  706.     }
  707.   /*
  708.    *    Set relocation base
  709.    */
  710.   PUT_CHAR (TIR_S_C_STO_PIDR);
  711.   /*
  712.    *    Flush the buffer if it is more than 75% full
  713.    */
  714.   if (Object_Record_Offset >
  715.       (sizeof (Object_Record_Buffer) * 3 / 4))
  716.     Flush_VMS_Object_Record_Buffer ();
  717. }
  718.  
  719. /*
  720.  *    Make a debugger reference to a struct, union or enum.
  721.  */
  722. static
  723. VMS_Store_Struct (Struct_Index)
  724.      int Struct_Index;
  725. {
  726.   /*
  727.    *    We are writing a "OBJ_S_C_DBG" record
  728.    */
  729.   Set_VMS_Object_File_Record (OBJ_S_C_DBG);
  730.   /*
  731.    *    If the buffer is empty we must insert the record type
  732.    */
  733.   if (Object_Record_Offset == 0)
  734.     PUT_CHAR (OBJ_S_C_DBG);
  735.   PUT_CHAR (TIR_S_C_STA_UW);
  736.   PUT_SHORT (Struct_Index);
  737.   PUT_CHAR (TIR_S_C_CTL_STKDL);
  738.   PUT_CHAR (TIR_S_C_STO_L);
  739.   /*
  740.    *    Flush the buffer if it is more than 75% full
  741.    */
  742.   if (Object_Record_Offset >
  743.       (sizeof (Object_Record_Buffer) * 3 / 4))
  744.     Flush_VMS_Object_Record_Buffer ();
  745. }
  746.  
  747. /*
  748.  *    Make a debugger reference to partially define a struct, union or enum.
  749.  */
  750. static
  751. VMS_Def_Struct (Struct_Index)
  752.      int Struct_Index;
  753. {
  754.   /*
  755.    *    We are writing a "OBJ_S_C_DBG" record
  756.    */
  757.   Set_VMS_Object_File_Record (OBJ_S_C_DBG);
  758.   /*
  759.    *    If the buffer is empty we must insert the record type
  760.    */
  761.   if (Object_Record_Offset == 0)
  762.     PUT_CHAR (OBJ_S_C_DBG);
  763.   PUT_CHAR (TIR_S_C_STA_UW);
  764.   PUT_SHORT (Struct_Index);
  765.   PUT_CHAR (TIR_S_C_CTL_DFLOC);
  766.   /*
  767.    *    Flush the buffer if it is more than 75% full
  768.    */
  769.   if (Object_Record_Offset >
  770.       (sizeof (Object_Record_Buffer) * 3 / 4))
  771.     Flush_VMS_Object_Record_Buffer ();
  772. }
  773.  
  774. static
  775. VMS_Set_Struct (Struct_Index)
  776.      int Struct_Index;
  777. {                /* see previous functions for comments */
  778.   Set_VMS_Object_File_Record (OBJ_S_C_DBG);
  779.   if (Object_Record_Offset == 0)
  780.     PUT_CHAR (OBJ_S_C_DBG);
  781.   PUT_CHAR (TIR_S_C_STA_UW);
  782.   PUT_SHORT (Struct_Index);
  783.   PUT_CHAR (TIR_S_C_CTL_STLOC);
  784.   if (Object_Record_Offset >
  785.       (sizeof (Object_Record_Buffer) * 3 / 4))
  786.     Flush_VMS_Object_Record_Buffer ();
  787. }
  788.  
  789. /*
  790.  *    Write the Traceback Module Begin record
  791.  */
  792. static
  793. VMS_TBT_Module_Begin ()
  794. {
  795.   register char *cp, *cp1;
  796.   int Size;
  797.   char Module_Name[256];
  798.   char Local[256];
  799.  
  800.   /*
  801.    *    Get module name (the FILENAME part of the object file)
  802.    */
  803.   cp = out_file_name;
  804.   cp1 = Module_Name;
  805.   while (*cp)
  806.     {
  807.       if ((*cp == ']') || (*cp == '>') ||
  808.       (*cp == ':') || (*cp == '/'))
  809.     {
  810.       cp1 = Module_Name;
  811.       cp++;
  812.       continue;
  813.     }
  814.       *cp1++ = islower (*cp) ? toupper (*cp++) : *cp++;
  815.     }
  816.   *cp1 = 0;
  817.   /*
  818.    *    Limit it to 31 characters
  819.    */
  820.   while (--cp1 >= Module_Name)
  821.     if (*cp1 == '.')
  822.       *cp1 = 0;
  823.   if (strlen (Module_Name) > 31)
  824.     {
  825.       if (flag_hash_long_names)
  826.     printf ("%s: Module name truncated: %s\n", myname, Module_Name);
  827.       Module_Name[31] = 0;
  828.     }
  829.   /*
  830.    *    Arrange to store the data locally (leave room for size byte)
  831.    */
  832.   cp = Local + 1;
  833.   /*
  834.    *    Begin module
  835.    */
  836.   *cp++ = DST_S_C_MODBEG;
  837.   /*
  838.    *    Unused
  839.    */
  840.   *cp++ = 0;
  841.   /*
  842.    *    Language type == "C"
  843.    */
  844.   COPY_LONG (cp, DST_S_C_C);
  845.   cp += sizeof (long);
  846.   /*
  847.    *    Store the module name
  848.    */
  849.   *cp++ = strlen (Module_Name);
  850.   cp1 = Module_Name;
  851.   while (*cp1)
  852.     *cp++ = *cp1++;
  853.   /*
  854.    *    Now we can store the record size
  855.    */
  856.   Size = (cp - Local);
  857.   Local[0] = Size - 1;
  858.   /*
  859.    *    Put it into the object record
  860.    */
  861.   VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
  862. }
  863.  
  864.  
  865. /*
  866.  *    Write the Traceback Module End record
  867. */
  868. static
  869. VMS_TBT_Module_End ()
  870. {
  871.   char Local[2];
  872.  
  873.   /*
  874.    *    End module
  875.    */
  876.   Local[0] = 1;
  877.   Local[1] = DST_S_C_MODEND;
  878.   /*
  879.    *    Put it into the object record
  880.    */
  881.   VMS_Store_Immediate_Data (Local, 2, OBJ_S_C_TBT);
  882. }
  883.  
  884.  
  885. /*
  886.  *    Write the Traceback Routine Begin record
  887.  */
  888. static
  889. VMS_TBT_Routine_Begin (symbolP, Psect)
  890.      struct symbol *symbolP;
  891.      int Psect;
  892. {
  893.   register char *cp, *cp1;
  894.   char *Name;
  895.   int Offset;
  896.   int Size;
  897.   char Local[512];
  898.  
  899.   /*
  900.    *    Strip the leading "_" from the name
  901.    */
  902.   Name = S_GET_NAME (symbolP);
  903.   if (*Name == '_')
  904.     Name++;
  905.   /*
  906.    *    Get the text psect offset
  907.    */
  908.   Offset = S_GET_VALUE (symbolP);
  909.   /*
  910.    *    Calculate the record size
  911.    */
  912.   Size = 1 + 1 + 4 + 1 + strlen (Name);
  913.   /*
  914.    *    Record Size
  915.    */
  916.   Local[0] = Size;
  917.   /*
  918.    *    Begin Routine
  919.    */
  920.   Local[1] = DST_S_C_RTNBEG;
  921.   /*
  922.    *    Uses CallS/CallG
  923.    */
  924.   Local[2] = 0;
  925.   /*
  926.    *    Store the data so far
  927.    */
  928.   VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
  929.   /*
  930.    *    Make sure we are still generating a OBJ_S_C_TBT record
  931.    */
  932.   if (Object_Record_Offset == 0)
  933.     PUT_CHAR (OBJ_S_C_TBT);
  934.   /*
  935.    *    Now get the symbol address
  936.    */
  937.   PUT_CHAR (TIR_S_C_STA_WPL);
  938.   PUT_SHORT (Psect);
  939.   PUT_LONG (Offset);
  940.   /*
  941.    *    Store the data reference
  942.    */
  943.   PUT_CHAR (TIR_S_C_STO_PIDR);
  944.   /*
  945.    *    Store the counted string as data
  946.    */
  947.   cp = Local;
  948.   cp1 = Name;
  949.   Size = strlen (cp1) + 1;
  950.   *cp++ = Size - 1;
  951.   while (*cp1)
  952.     *cp++ = *cp1++;
  953.   VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
  954. }
  955.  
  956.  
  957. /*
  958.  *    Write the Traceback Routine End record
  959.  *     We *must* search the symbol table to find the next routine, since
  960.  *     the assember has a way of reassembling the symbol table OUT OF ORDER
  961.  *     Thus the next routine in the symbol list is not necessarily the
  962.  *    next one in memory.  For debugging to work correctly we must know the
  963.  *    size of the routine.
  964.  */
  965. static
  966. VMS_TBT_Routine_End (Max_Size, sp)
  967.      int Max_Size;
  968.      symbolS *sp;
  969. {
  970.   symbolS *symbolP;
  971.   int Size = 0x7fffffff;
  972.   char Local[16];
  973.   valueT sym_value, sp_value = S_GET_VALUE (sp);
  974.  
  975.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  976.     {
  977.       if (!S_IS_DEBUG (symbolP) && S_GET_TYPE (symbolP) == N_TEXT)
  978.     {
  979.       if (*S_GET_NAME (symbolP) == 'L')
  980.         continue;
  981.       sym_value = S_GET_VALUE (symbolP);
  982.       if (sym_value > sp_value && sym_value < Size)
  983.         Size = sym_value;
  984.  
  985.       /*
  986.        * Dummy labels like "gcc_compiled." should no longer reach here.
  987.        */
  988. #if 0
  989.       else
  990.       /* check if gcc_compiled. has size of zero */
  991.       if (sym_value == sp_value &&
  992.           sp != symbolP &&
  993.           (!strcmp (S_GET_NAME (sp), "gcc_compiled.") ||
  994.            !strcmp (S_GET_NAME (sp), "gcc2_compiled.")))
  995.         Size = sym_value;
  996. #endif
  997.     }
  998.     }
  999.   if (Size == 0x7fffffff)
  1000.     Size = Max_Size;
  1001.   Size -= sp_value;        /* and get the size of the routine */
  1002.   /*
  1003.    *    Record Size
  1004.    */
  1005.   Local[0] = 6;
  1006.   /*
  1007.    *    End of Routine
  1008.    */
  1009.   Local[1] = DST_S_C_RTNEND;
  1010.   /*
  1011.    *    Unused
  1012.    */
  1013.   Local[2] = 0;
  1014.   /*
  1015.    *    Size of routine
  1016.    */
  1017.   COPY_LONG (&Local[3], Size);
  1018.   /*
  1019.    *    Store the record
  1020.    */
  1021.   VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
  1022. }
  1023.  
  1024. /*
  1025.  *    Write the Traceback Block End record
  1026.  */
  1027. static
  1028. VMS_TBT_Block_Begin (symbolP, Psect, Name)
  1029.      struct symbol *symbolP;
  1030.      int Psect;
  1031.      char *Name;
  1032. {
  1033.   register char *cp, *cp1;
  1034.   int Offset;
  1035.   int Size;
  1036.   char Local[512];
  1037.   /*
  1038.    *    Begin block
  1039.    */
  1040.   Size = 1 + 1 + 4 + 1 + strlen (Name);
  1041.   /*
  1042.    *    Record Size
  1043.    */
  1044.   Local[0] = Size;
  1045.   /*
  1046.    *    Begin Block - We simulate with a phony routine
  1047.    */
  1048.   Local[1] = DST_S_C_BLKBEG;
  1049.   /*
  1050.    *    Uses CallS/CallG
  1051.    */
  1052.   Local[2] = 0;
  1053.   /*
  1054.    *    Store the data so far
  1055.    */
  1056.   VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_DBG);
  1057.   /*
  1058.    *    Make sure we are still generating a OBJ_S_C_DBG record
  1059.    */
  1060.   if (Object_Record_Offset == 0)
  1061.     PUT_CHAR (OBJ_S_C_DBG);
  1062.   /*
  1063.    *    Now get the symbol address
  1064.    */
  1065.   PUT_CHAR (TIR_S_C_STA_WPL);
  1066.   PUT_SHORT (Psect);
  1067.   /*
  1068.    *    Get the text psect offset
  1069.    */
  1070.   Offset = S_GET_VALUE (symbolP);
  1071.   PUT_LONG (Offset);
  1072.   /*
  1073.    *    Store the data reference
  1074.    */
  1075.   PUT_CHAR (TIR_S_C_STO_PIDR);
  1076.   /*
  1077.    *    Store the counted string as data
  1078.    */
  1079.   cp = Local;
  1080.   cp1 = Name;
  1081.   Size = strlen (cp1) + 1;
  1082.   *cp++ = Size - 1;
  1083.   while (*cp1)
  1084.     *cp++ = *cp1++;
  1085.   VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_DBG);
  1086. }
  1087.  
  1088.  
  1089. /*
  1090.  *    Write the Traceback Block End record
  1091.  */
  1092. static
  1093. VMS_TBT_Block_End (Size)
  1094.      int Size;
  1095. {
  1096.   char Local[16];
  1097.  
  1098.   /*
  1099.    *    End block - simulate with a phony end routine
  1100.    */
  1101.   Local[0] = 6;
  1102.   Local[1] = DST_S_C_BLKEND;
  1103.   COPY_LONG (&Local[3], Size);
  1104.   /*
  1105.    *    Unused
  1106.    */
  1107.   Local[2] = 0;
  1108.   VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_DBG);
  1109. }
  1110.  
  1111.  
  1112.  
  1113. /*
  1114.  *    Write a Line number / PC correlation record
  1115.  */
  1116. static
  1117. VMS_TBT_Line_PC_Correlation (Line_Number, Offset, Psect, Do_Delta)
  1118.      int Line_Number;
  1119.      int Offset;
  1120.      int Psect;
  1121.      int Do_Delta;
  1122. {
  1123.   register char *cp;
  1124.   char Local[64];
  1125.  
  1126.   /*
  1127. *    If not delta, set our PC/Line number correlation
  1128. */
  1129.   if (Do_Delta == 0)
  1130.     {
  1131.       /*
  1132.        *    Size
  1133.        */
  1134.       Local[0] = 1 + 1 + 2 + 1 + 4;
  1135.       /*
  1136.        *    Line Number/PC correlation
  1137.        */
  1138.       Local[1] = DST_S_C_LINE_NUM;
  1139.       /*
  1140.        *    Set Line number
  1141.        */
  1142.       Local[2] = DST_S_C_SET_LINE_NUM;
  1143.       COPY_SHORT (&Local[3], Line_Number - 1);
  1144.       /*
  1145.        *    Set PC
  1146.        */
  1147.       Local[5] = DST_S_C_SET_ABS_PC;
  1148.       VMS_Store_Immediate_Data (Local, 6, OBJ_S_C_TBT);
  1149.       /*
  1150.        *    Make sure we are still generating a OBJ_S_C_TBT record
  1151.        */
  1152.       if (Object_Record_Offset == 0)
  1153.     PUT_CHAR (OBJ_S_C_TBT);
  1154.       if (Psect < 255)
  1155.     {
  1156.       PUT_CHAR (TIR_S_C_STA_PL);
  1157.       PUT_CHAR (Psect);
  1158.     }
  1159.       else
  1160.     {
  1161.       PUT_CHAR (TIR_S_C_STA_WPL);
  1162.       PUT_SHORT (Psect);
  1163.     }
  1164.       PUT_LONG (Offset);
  1165.       PUT_CHAR (TIR_S_C_STO_PIDR);
  1166.       /*
  1167.        *    Do a PC offset of 0 to register the line number
  1168.        */
  1169.       Local[0] = 2;
  1170.       Local[1] = DST_S_C_LINE_NUM;
  1171.       Local[2] = 0;        /* Increment PC by 0 and register line # */
  1172.       VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
  1173.     }
  1174.   else
  1175.     {
  1176.       /*
  1177.        *    If Delta is negative, terminate the line numbers
  1178.        */
  1179.       if (Do_Delta < 0)
  1180.     {
  1181.       Local[0] = 1 + 1 + 4;
  1182.       Local[1] = DST_S_C_LINE_NUM;
  1183.       Local[2] = DST_S_C_TERM_L;
  1184.       COPY_LONG (&Local[3], Offset);
  1185.       VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
  1186.       /*
  1187.        *    Done
  1188.        */
  1189.       return;
  1190.     }
  1191.       /*
  1192.        *    Do a PC/Line delta
  1193.        */
  1194.       cp = Local + 1;
  1195.       *cp++ = DST_S_C_LINE_NUM;
  1196.       if (Line_Number > 1)
  1197.     {
  1198.       /*
  1199.        *    We need to increment the line number
  1200.        */
  1201.       if (Line_Number - 1 <= 255)
  1202.         {
  1203.           *cp++ = DST_S_C_INCR_LINUM;
  1204.           *cp++ = Line_Number - 1;
  1205.         }
  1206.       else
  1207.         {
  1208.           *cp++ = DST_S_C_INCR_LINUM_W;
  1209.           COPY_SHORT (cp, Line_Number - 1);
  1210.           cp += sizeof (short);
  1211.         }
  1212.     }
  1213.       /*
  1214.        *    Increment the PC
  1215.        */
  1216.       if (Offset <= 128)
  1217.     {
  1218.       *cp++ = -Offset;
  1219.     }
  1220.       else
  1221.     {
  1222.       if (Offset < 0x10000)
  1223.         {
  1224.           *cp++ = DST_S_C_DELTA_PC_W;
  1225.           COPY_SHORT (cp, Offset);
  1226.           cp += sizeof (short);
  1227.         }
  1228.       else
  1229.         {
  1230.           *cp++ = DST_S_C_DELTA_PC_L;
  1231.           COPY_LONG (cp, Offset);
  1232.           cp += sizeof (long);
  1233.         }
  1234.     }
  1235.       Local[0] = cp - (Local + 1);
  1236.       VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
  1237.     }
  1238. }
  1239.  
  1240.  
  1241. /*
  1242.  *    Describe a source file to the debugger
  1243.  */
  1244. static
  1245. VMS_TBT_Source_File (Filename, ID_Number)
  1246.      char *Filename;
  1247.      int ID_Number;
  1248. {
  1249.   register char *cp, *cp1;
  1250.   int Status, i;
  1251.   char Local[512];
  1252. #ifndef VMS            /* Used for cross-assembly */
  1253.   i = strlen (Filename);
  1254. #else /* VMS */
  1255.   static struct FAB Fab;
  1256.   static struct NAM Nam;
  1257.   static struct XABDAT Date_Xab;
  1258.   static struct XABFHC File_Header_Xab;
  1259.   char Es_String[255], Rs_String[255];
  1260.  
  1261.   /*
  1262.    *    Setup the Fab
  1263.    */
  1264.   Fab.fab$b_bid = FAB$C_BID;
  1265.   Fab.fab$b_bln = sizeof (Fab);
  1266.   Fab.fab$l_nam = (&Nam);
  1267.   Fab.fab$l_xab = (char *) &Date_Xab;
  1268.   /*
  1269.    *    Setup the Nam block so we can find out the FULL name
  1270.    *    of the source file.
  1271.    */
  1272.   Nam.nam$b_bid = NAM$C_BID;
  1273.   Nam.nam$b_bln = sizeof (Nam);
  1274.   Nam.nam$l_rsa = Rs_String;
  1275.   Nam.nam$b_rss = sizeof (Rs_String);
  1276.   Nam.nam$l_esa = Es_String;
  1277.   Nam.nam$b_ess = sizeof (Es_String);
  1278.   /*
  1279.    *    Setup the Date and File Header Xabs
  1280.    */
  1281.   Date_Xab.xab$b_cod = XAB$C_DAT;
  1282.   Date_Xab.xab$b_bln = sizeof (Date_Xab);
  1283.   Date_Xab.xab$l_nxt = (char *) &File_Header_Xab;
  1284.   File_Header_Xab.xab$b_cod = XAB$C_FHC;
  1285.   File_Header_Xab.xab$b_bln = sizeof (File_Header_Xab);
  1286.   /*
  1287.    *    Get the file information
  1288.    */
  1289.   Fab.fab$l_fna = Filename;
  1290.   Fab.fab$b_fns = strlen (Filename);
  1291.   Status = sys$open (&Fab);
  1292.   if (!(Status & 1))
  1293.     {
  1294.       printf ("gas: Couldn't find source file \"%s\", status=%%X%x\n",
  1295.           Filename, Status);
  1296.       return (0);
  1297.     }
  1298.   sys$close (&Fab);
  1299.   /*
  1300.    *    Calculate the size of the resultant string
  1301.    */
  1302.   i = Nam.nam$b_rsl;
  1303. #endif /* VMS */
  1304.   /*
  1305.    *    Size of record
  1306.    */
  1307.   Local[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i + 1;
  1308.   /*
  1309.    *    Source declaration
  1310.    */
  1311.   Local[1] = DST_S_C_SOURCE;
  1312.   /*
  1313.    *    Make formfeeds count as source records
  1314.    */
  1315.   Local[2] = DST_S_C_SRC_FORMFEED;
  1316.   /*
  1317.    *    Declare source file
  1318.    */
  1319.   Local[3] = DST_S_C_SRC_DECLFILE;
  1320.   Local[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i + 1;
  1321.   cp = Local + 5;
  1322.   /*
  1323.    *    Flags
  1324.    */
  1325.   *cp++ = 0;
  1326.   /*
  1327.    *    File ID
  1328.    */
  1329.   COPY_SHORT (cp, ID_Number);
  1330.   cp += sizeof (short);
  1331. #ifndef VMS
  1332.   /*
  1333.    *    Creation Date.  Unknown, so we fill with zeroes.
  1334.    */
  1335.   *(long *) cp = 0;
  1336.   cp += sizeof (long);
  1337.   *(long *) cp = 0;
  1338.   cp += sizeof (long);
  1339.   /*
  1340.    *    End of file block
  1341.    */
  1342.   *(long *) cp = 0;
  1343.   cp += sizeof (long);
  1344.   /*
  1345.    *    First free byte
  1346.    */
  1347.   *(short *) cp = 0;
  1348.   cp += sizeof (short);
  1349.   /*
  1350.    *    Record format
  1351.    */
  1352.   *cp++ = 0;
  1353.   /*
  1354.    *    Filename
  1355.    */
  1356.   *cp++ = i;
  1357.   cp1 = Filename;
  1358. #else /* Use this code when assembling for VMS on a VMS system */
  1359.   /*
  1360.    *    Creation Date
  1361.    */
  1362.   *(long *) cp = ((long *) &Date_Xab.xab$q_cdt)[0];
  1363.   cp += sizeof (long);
  1364.   *(long *) cp = ((long *) &Date_Xab.xab$q_cdt)[1];
  1365.   cp += sizeof (long);
  1366.   /*
  1367.    *    End of file block
  1368.    */
  1369.   *(long *) cp = File_Header_Xab.xab$l_ebk;
  1370.   cp += sizeof (long);
  1371.   /*
  1372.    *    First free byte
  1373.    */
  1374.   *(short *) cp = File_Header_Xab.xab$w_ffb;
  1375.   cp += sizeof (short);
  1376.   /*
  1377.    *    Record format
  1378.    */
  1379.   *cp++ = File_Header_Xab.xab$b_rfo;
  1380.   /*
  1381.    *    Filename
  1382.    */
  1383.   *cp++ = i;
  1384.   cp1 = Rs_String;
  1385. #endif /* VMS */
  1386.   while (--i >= 0)
  1387.     *cp++ = *cp1++;
  1388.   /*
  1389.    *    Library module name (none)
  1390.    */
  1391.   *cp++ = 0;
  1392.   /*
  1393.    *    Done
  1394.    */
  1395.   VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
  1396.   return 1;
  1397. }
  1398.  
  1399.  
  1400. /*
  1401.  *    Give the number of source lines to the debugger
  1402.  */
  1403. static
  1404. VMS_TBT_Source_Lines (ID_Number, Starting_Line_Number, Number_Of_Lines)
  1405.      int ID_Number;
  1406.      int Starting_Line_Number;
  1407.      int Number_Of_Lines;
  1408. {
  1409.   char *cp, *cp1;
  1410.   char Local[16];
  1411.  
  1412.   /*
  1413.    *    Size of record
  1414.    */
  1415.   Local[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
  1416.   /*
  1417.    *    Source declaration
  1418.    */
  1419.   Local[1] = DST_S_C_SOURCE;
  1420.   /*
  1421.    *    Set Source File
  1422.    */
  1423.   cp = Local + 2;
  1424.   *cp++ = DST_S_C_SRC_SETFILE;
  1425.   /*
  1426.    *    File ID Number
  1427.    */
  1428.   COPY_SHORT (cp, ID_Number);
  1429.   cp += sizeof (short);
  1430.   /*
  1431.    *    Set record number
  1432.    */
  1433.   *cp++ = DST_S_C_SRC_SETREC_L;
  1434.   COPY_LONG (cp, Starting_Line_Number);
  1435.   cp += sizeof (long);
  1436.   /*
  1437.    *    Define lines
  1438.    */
  1439.   *cp++ = DST_S_C_SRC_DEFLINES_W;
  1440.   COPY_SHORT (cp, Number_Of_Lines);
  1441.   cp += sizeof (short);
  1442.   /*
  1443.    *    Done
  1444.    */
  1445.   VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
  1446. }
  1447.  
  1448.  
  1449.  
  1450.  
  1451. /* This routine locates a file in the list of files.  If an entry does not
  1452.  * exist, one is created.  For include files, a new entry is always created
  1453.  * such that inline functions can be properly debugged. */
  1454. static struct input_file *
  1455. find_file (sp)
  1456.      symbolS *sp;
  1457. {
  1458.   struct input_file *same_file;
  1459.   struct input_file *fpnt;
  1460.   same_file = (struct input_file *) NULL;
  1461.   for (fpnt = file_root; fpnt; fpnt = fpnt->next)
  1462.     {
  1463.       if (fpnt == (struct input_file *) NULL)
  1464.     break;
  1465.       if (fpnt->spnt == sp)
  1466.     return fpnt;
  1467.     }
  1468.   for (fpnt = file_root; fpnt; fpnt = fpnt->next)
  1469.     {
  1470.       if (fpnt == (struct input_file *) NULL)
  1471.     break;
  1472.       if (strcmp (S_GET_NAME (sp), fpnt->name) == 0)
  1473.     {
  1474.       if (fpnt->flag == 1)
  1475.         return fpnt;
  1476.       same_file = fpnt;
  1477.       break;
  1478.     }
  1479.     }
  1480.   fpnt = (struct input_file *) xmalloc (sizeof (struct input_file));
  1481.   if (file_root == (struct input_file *) NULL)
  1482.     file_root = fpnt;
  1483.   else
  1484.     {
  1485.       struct input_file *fpnt1;
  1486.       for (fpnt1 = file_root; fpnt1->next; fpnt1 = fpnt1->next) ;
  1487.       fpnt1->next = fpnt;
  1488.     }
  1489.   fpnt->next = (struct input_file *) NULL;
  1490.   fpnt->name = S_GET_NAME (sp);
  1491.   fpnt->min_line = 0x7fffffff;
  1492.   fpnt->max_line = 0;
  1493.   fpnt->offset = 0;
  1494.   fpnt->flag = 0;
  1495.   fpnt->file_number = 0;
  1496.   fpnt->spnt = sp;
  1497.   fpnt->same_file_fpnt = same_file;
  1498.   return fpnt;
  1499. }
  1500.  
  1501. /*
  1502.  * The following functions and definitions are used to generate object records
  1503.  * that will describe program variables to the VMS debugger.
  1504.  *
  1505.  * This file contains many of the routines needed to output debugging info into
  1506.  * the object file that the VMS debugger needs to understand symbols.  These
  1507.  * routines are called very late in the assembly process, and thus we can be
  1508.  * fairly lax about changing things, since the GSD and the TIR sections have
  1509.  * already been output.
  1510.  */
  1511.  
  1512.  
  1513. /* This routine converts a number string into an integer, and stops when it
  1514.  * sees an invalid character.  The return value is the address of the character
  1515.  * just past the last character read.  No error is generated.
  1516.  */
  1517. static char *
  1518. cvt_integer (str, rtn)
  1519.      char *str;
  1520.      int *rtn;
  1521. {
  1522.   int ival, neg;
  1523.   neg = *str == '-' ? ++str, -1 : 1;
  1524.   ival = 0;
  1525.   while ((*str <= '9') && (*str >= '0'))
  1526.     ival = 10 * ival + *str++ - '0';
  1527.   *rtn = neg * ival;
  1528.   return str;
  1529. }
  1530.  
  1531. /* this routine fixes the names that are generated by C++, ".this" is a good
  1532.  * example.  The period does not work for the debugger, since it looks like
  1533.  * the syntax for a structure element, and thus it gets mightily confused
  1534.  *
  1535.  * We also use this to strip the PsectAttribute hack from the name before we
  1536.  * write a debugger record */
  1537.  
  1538. static char *
  1539. fix_name (pnt)
  1540.      char *pnt;
  1541. {
  1542.   char *pnt1;
  1543.   /*
  1544.    *    Kill any leading "_"
  1545.    */
  1546.   if (*pnt == '_')
  1547.     pnt++;
  1548.   /*
  1549.    *    Is there a Psect Attribute to skip??
  1550.    */
  1551.   if (HAS_PSECT_ATTRIBUTES (pnt))
  1552.     {
  1553.       /*
  1554.        *    Yes: Skip it
  1555.        */
  1556.       pnt += PSECT_ATTRIBUTES_STRING_LENGTH;
  1557.       while (*pnt)
  1558.     {
  1559.       if ((pnt[0] == '$') && (pnt[1] == '$'))
  1560.         {
  1561.           pnt += 2;
  1562.           break;
  1563.         }
  1564.       pnt++;
  1565.     }
  1566.     }
  1567. /* Here we fix the .this -> $this conversion */
  1568.   for (pnt1 = pnt; *pnt1 != 0; pnt1++)
  1569.     {
  1570.       if (*pnt1 == '.')
  1571.     *pnt1 = '$';
  1572.     }
  1573.   return pnt;
  1574. }
  1575.  
  1576. /* When defining a structure, this routine is called to find the name of
  1577.  * the actual structure.  It is assumed that str points to the equal sign
  1578.  * in the definition, and it moves backward until it finds the start of the
  1579.  * name.  If it finds a 0, then it knows that this structure def is in the
  1580.  * outermost level, and thus symbol_name points to the symbol name.
  1581.  */
  1582. static char *
  1583. get_struct_name (str)
  1584.      char *str;
  1585. {
  1586.   char *pnt;
  1587.   pnt = str;
  1588.   while ((*pnt != ':') && (*pnt != '\0'))
  1589.     pnt--;
  1590.   if (*pnt == '\0')
  1591.     return symbol_name;
  1592.   *pnt-- = '\0';
  1593.   while ((*pnt != ';') && (*pnt != '='))
  1594.     pnt--;
  1595.   if (*pnt == ';')
  1596.     return pnt + 1;
  1597.   while ((*pnt < '0') || (*pnt > '9'))
  1598.     pnt++;
  1599.   while ((*pnt >= '0') && (*pnt <= '9'))
  1600.     pnt++;
  1601.   return pnt;
  1602. }
  1603.  
  1604. /* search symbol list for type number dbx_type.  Return a pointer to struct */
  1605. static struct VMS_DBG_Symbol *
  1606. find_symbol (dbx_type)
  1607.      int dbx_type;
  1608. {
  1609.   struct VMS_DBG_Symbol *spnt;
  1610.   spnt = VMS_Symbol_type_list;
  1611.   while (spnt != (struct VMS_DBG_Symbol *) NULL)
  1612.     {
  1613.       if (spnt->dbx_type == dbx_type)
  1614.     break;
  1615.       spnt = spnt->next;
  1616.     }
  1617.   if (spnt == (struct VMS_DBG_Symbol *) NULL)
  1618.     return 0;            /*Dunno what this is*/
  1619.   if(spnt->advanced == ALIAS)
  1620.     return find_symbol(spnt->type2);
  1621.   return spnt;
  1622. }
  1623.  
  1624.  
  1625. /* this routine puts info into either Local or Asuffix, depending on the sign
  1626.  * of size.  The reason is that it is easier to build the variable descriptor
  1627.  * backwards, while the array descriptor is best built forwards.  In the end
  1628.  * they get put together, if there is not a struct/union/enum along the way
  1629.  */
  1630. static
  1631. push (value, size)
  1632.      int value, size;
  1633. {
  1634.   int i;
  1635.   int size1;
  1636.   size1 = size;
  1637.   if (size < 0)
  1638.     {
  1639.       size1 = -size;
  1640.       if (Lpnt < size1)
  1641.     {
  1642.       overflow = 1;
  1643.       Lpnt = 1;
  1644.       return;
  1645.     }
  1646.       Lpnt -= size1;
  1647.       md_number_to_chars (&Local[Lpnt + 1], value, size1);
  1648.     }
  1649.   else
  1650.     {
  1651.       if (Apoint + size1 >= MAX_DEBUG_RECORD)
  1652.     {
  1653.       overflow = 1;
  1654.       Apoint = MAX_DEBUG_RECORD - 1;
  1655.       return;
  1656.     }
  1657.       md_number_to_chars (&Asuffix[Apoint], value, size1);
  1658.       Apoint += size1;
  1659.     }
  1660. }
  1661.  
  1662. /* this routine generates the array descriptor for a given array */
  1663. static
  1664. array_suffix (spnt2)
  1665.      struct VMS_DBG_Symbol *spnt2;
  1666. {
  1667.   struct VMS_DBG_Symbol *spnt;
  1668.   struct VMS_DBG_Symbol *spnt1;
  1669.   int rank;
  1670.   int total_size;
  1671.   int i;
  1672.   rank = 0;
  1673.   spnt = spnt2;
  1674.   while (spnt->advanced != ARRAY)
  1675.     {
  1676.       spnt = find_symbol (spnt->type2);
  1677.       if (spnt == (struct VMS_DBG_Symbol *) NULL)
  1678.     return;
  1679.     }
  1680.   spnt1 = spnt;
  1681.   spnt1 = spnt;
  1682.   total_size = 1;
  1683.   while (spnt1->advanced == ARRAY)
  1684.     {
  1685.       rank++;
  1686.       total_size *= (spnt1->index_max - spnt1->index_min + 1);
  1687.       spnt1 = find_symbol (spnt1->type2);
  1688.     }
  1689.   total_size = total_size * spnt1->data_size;
  1690.   push (spnt1->data_size, 2);    /* element size */
  1691.   if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
  1692.     push (0, 1);
  1693.   else
  1694.     push (spnt1->VMS_type, 1);    /* element type */
  1695.   push (DSC_K_CLASS_A, 1);    /* descriptor class */
  1696.   push (0, 4);            /* base address */
  1697.   push (0, 1);            /* scale factor -- not applicable */
  1698.   push (0, 1);            /* digit count -- not applicable */
  1699.   push (0xc0, 1);        /* flags: multiplier block & bounds present */
  1700.   push (rank, 1);        /* number of dimensions */
  1701.   push (total_size, 4);
  1702.   push (0, 4);            /* pointer to element [0][0]...[0] */
  1703.   spnt1 = spnt;
  1704.   while (spnt1->advanced == ARRAY)
  1705.     {
  1706.       push (spnt1->index_max - spnt1->index_min + 1, 4);
  1707.       spnt1 = find_symbol (spnt1->type2);
  1708.     }
  1709.   spnt1 = spnt;
  1710.   while (spnt1->advanced == ARRAY)
  1711.     {
  1712.       push (spnt1->index_min, 4);
  1713.       push (spnt1->index_max, 4);
  1714.       spnt1 = find_symbol (spnt1->type2);
  1715.     }
  1716. }
  1717.  
  1718. /* this routine generates the start of a variable descriptor based upon
  1719.  * a struct/union/enum that has yet to be defined.  We define this spot as
  1720.  * a new location, and save four bytes for the address.  When the struct is
  1721.  * finally defined, then we can go back and plug in the correct address.
  1722. */
  1723. static
  1724. new_forward_ref (dbx_type)
  1725.      int dbx_type;
  1726. {
  1727.   struct forward_ref *fpnt;
  1728.   fpnt = (struct forward_ref *) xmalloc (sizeof (struct forward_ref));
  1729.   fpnt->next = f_ref_root;
  1730.   f_ref_root = fpnt;
  1731.   fpnt->dbx_type = dbx_type;
  1732.   fpnt->struc_numb = ++structure_count;
  1733.   fpnt->resolved = 'N';
  1734.   push (DST_K_TS_IND, -1);    /* indirect type specification */
  1735.   total_len = 5;
  1736.   push (total_len, -2);
  1737.   struct_number = -fpnt->struc_numb;
  1738. }
  1739.  
  1740. /* this routine generates the variable descriptor used to describe non-basic
  1741.  * variables.  It calls itself recursively until it gets to the bottom of it
  1742.  * all, and then builds the descriptor backwards.  It is easiest to do it this
  1743.  *way since we must periodically write length bytes, and it is easiest if we know
  1744.  *the value when it is time to write it.
  1745.  */
  1746. static int
  1747. gen1 (spnt, array_suffix_len)
  1748.      struct VMS_DBG_Symbol *spnt;
  1749.      int array_suffix_len;
  1750. {
  1751.   struct VMS_DBG_Symbol *spnt1;
  1752.   int i;
  1753.   switch (spnt->advanced)
  1754.     {
  1755.     case VOID:
  1756.       push (DBG_S_C_VOID, -1);
  1757.       total_len += 1;
  1758.       push (total_len, -2);
  1759.       return 0;
  1760.     case BASIC:
  1761.     case FUNCTION:
  1762.       if (array_suffix_len == 0)
  1763.     {
  1764.       push (spnt->VMS_type, -1);
  1765.       push (DBG_S_C_BASIC, -1);
  1766.       total_len = 2;
  1767.       push (total_len, -2);
  1768.       return 1;
  1769.     }
  1770.       push (0, -4);
  1771.       push (DST_K_VFLAGS_DSC, -1);
  1772.       push (DST_K_TS_DSC, -1);    /* descriptor type specification */
  1773.       total_len = -2;
  1774.       return 1;
  1775.     case STRUCT:
  1776.     case UNION:
  1777.     case ENUM:
  1778.       struct_number = spnt->struc_numb;
  1779.       if (struct_number < 0)
  1780.     {
  1781.       new_forward_ref (spnt->dbx_type);
  1782.       return 1;
  1783.     }
  1784.       push (DBG_S_C_STRUCT, -1);
  1785.       total_len = 5;
  1786.       push (total_len, -2);
  1787.       return 1;
  1788.     case POINTER:
  1789.       spnt1 = find_symbol (spnt->type2);
  1790.       i = 1;
  1791.       if (!spnt1)
  1792.     new_forward_ref (spnt->type2);
  1793.       else
  1794.     i = gen1 (spnt1, 0);
  1795.       if (i)
  1796.     {            /* (*void) is a special case, do not put pointer suffix*/
  1797.       push (DBG_S_C_POINTER, -1);
  1798.       total_len += 3;
  1799.       push (total_len, -2);
  1800.     }
  1801.       return 1;
  1802.     case ARRAY:
  1803.       spnt1 = spnt;
  1804.       while (spnt1->advanced == ARRAY)
  1805.     {
  1806.       spnt1 = find_symbol (spnt1->type2);
  1807.       if (!spnt1)
  1808.         {
  1809.           printf ("gcc-as warning(debugger output):");
  1810.           printf ("Forward reference error, dbx type %d\n",
  1811.               spnt->type2);
  1812.           return;
  1813.         }
  1814.     }
  1815. /* It is too late to generate forward references, so the user gets a message.
  1816.  * This should only happen on a compiler error */
  1817.       i = gen1 (spnt1, 1);
  1818.       i = Apoint;
  1819.       array_suffix (spnt);
  1820.       array_suffix_len = Apoint - i;
  1821.       switch (spnt1->advanced)
  1822.     {
  1823.     case BASIC:
  1824.     case FUNCTION:
  1825.       break;
  1826.     default:
  1827.       push (0, -2);
  1828.       total_len += 2;
  1829.       push (total_len, -2);
  1830.       push (DST_K_VFLAGS_DSC, -1);
  1831.       push (1, -1);        /* flags: element value spec included */
  1832.       push (1, -1);        /* one dimension */
  1833.       push (DBG_S_C_COMPLEX_ARRAY, -1);
  1834.     }
  1835.       total_len += array_suffix_len + 8;
  1836.       push (total_len, -2);
  1837.     }
  1838. }
  1839.  
  1840. /* This generates a suffix for a variable.  If it is not a defined type yet,
  1841.  * then dbx_type contains the type we are expecting so we can generate a
  1842.  * forward reference.  This calls gen1 to build most of the descriptor, and
  1843.  * then it puts the icing on at the end.  It then dumps whatever is needed
  1844.  * to get a complete descriptor (i.e. struct reference, array suffix ).
  1845.  */
  1846. static
  1847. generate_suffix (spnt, dbx_type)
  1848.      struct VMS_DBG_Symbol *spnt;
  1849.      int dbx_type;
  1850. {
  1851.   static CONST char pvoid[6] = {
  1852.         5,        /* record.length == 5 */
  1853.         DST_K_TYPSPEC,    /* record.type == 1 (type specification) */
  1854.         0,        /* name.length == 0, no name follows */
  1855.         1, 0,        /* type.length == 1 {2 bytes, little endian} */
  1856.         DBG_S_C_VOID    /* type.type == 5 (pointer to unspecified) */
  1857.   };
  1858.   int ilen;
  1859.   int i;
  1860.   struct VMS_DBG_Symbol *spnt1;
  1861.   Apoint = 0;
  1862.   Lpnt = MAX_DEBUG_RECORD - 1;
  1863.   total_len = 0;
  1864.   struct_number = 0;
  1865.   overflow = 0;
  1866.   if (!spnt)
  1867.     new_forward_ref (dbx_type);
  1868.   else
  1869.     {
  1870.       if (spnt->VMS_type != DBG_S_C_ADVANCED_TYPE)
  1871.     return 0;        /* no suffix needed */
  1872.       gen1 (spnt, 0);
  1873.     }
  1874.   push (0, -1);        /* no name (len==0) */
  1875.   push (DST_K_TYPSPEC, -1);
  1876.   total_len += 4;
  1877.   push (total_len, -1);
  1878. /* if the variable descriptor overflows the record, output a descriptor for
  1879.  * a pointer to void.
  1880.  */
  1881.   if ((total_len >= MAX_DEBUG_RECORD) || overflow)
  1882.     {
  1883.       printf (" Variable descriptor %d too complicated. Defined as *void ", spnt->dbx_type);
  1884.       VMS_Store_Immediate_Data (pvoid, 6, OBJ_S_C_DBG);
  1885.       return;
  1886.     }
  1887.   i = 0;
  1888.   while (Lpnt < MAX_DEBUG_RECORD - 1)
  1889.     Local[i++] = Local[++Lpnt];
  1890.   Lpnt = i;
  1891. /* we use this for a reference to a structure that has already been defined */
  1892.   if (struct_number > 0)
  1893.     {
  1894.       VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
  1895.       Lpnt = 0;
  1896.       VMS_Store_Struct (struct_number);
  1897.     }
  1898. /* we use this for a forward reference to a structure that has yet to be
  1899. *defined.  We store four bytes of zero to make room for the actual address once
  1900. * it is known
  1901. */
  1902.   if (struct_number < 0)
  1903.     {
  1904.       struct_number = -struct_number;
  1905.       VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
  1906.       Lpnt = 0;
  1907.       VMS_Def_Struct (struct_number);
  1908.       COPY_LONG(&Local[Lpnt], 0L);
  1909.       Lpnt += 4;
  1910.       VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
  1911.       Lpnt = 0;
  1912.     }
  1913.   i = 0;
  1914.   while (i < Apoint)
  1915.     Local[Lpnt++] = Asuffix[i++];
  1916.   if (Lpnt != 0)
  1917.     VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
  1918.   Lpnt = 0;
  1919. }
  1920.  
  1921.     /* "novel length" type doesn't work for simple atomic types */
  1922. #define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
  1923. #undef SETUP_BASIC_TYPES
  1924.  
  1925. static void
  1926. bitfield_suffix (spnt, width)
  1927.      struct VMS_DBG_Symbol *spnt;
  1928.      int width;
  1929. {
  1930.   Local[Lpnt++] = 13;            /* rec.len==13 */
  1931.   Local[Lpnt++] = DST_K_TYPSPEC;    /* a type specification record */
  1932.   Local[Lpnt++] = 0;            /* not named */
  1933.   COPY_SHORT(&Local[Lpnt], 9);        /* typ.len==9 */
  1934.   Lpnt += 2;
  1935.   Local[Lpnt++] = DST_K_TS_NOV_LENG;    /* This type is a "novel length"
  1936.                        incarnation of some other type.  */
  1937.   COPY_LONG(&Local[Lpnt], width);    /* size in bits == novel length */
  1938.   Lpnt += 4;
  1939.   VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
  1940.   Lpnt = 0;
  1941.   /* assert( spnt->struc_numb > 0 ); */
  1942.   VMS_Store_Struct (spnt->struc_numb);    /* output 4 more bytes */
  1943. }
  1944.  
  1945. /* Formally define a builtin type, so that it can serve as the target of
  1946.    an indirect reference.  It makes bitfield_suffix() easier by avoiding
  1947.    the need to use a forward reference for the first occurrence of each
  1948.    type used in a bitfield.  */
  1949. static void
  1950. setup_basic_type (spnt)
  1951.      struct VMS_DBG_Symbol *spnt;
  1952. {
  1953. #ifdef SETUP_BASIC_TYPES
  1954.   /* This would be very useful if "novel length" fields actually worked
  1955.      with basic types like they do with enumerated types.  However,
  1956.      they do not, so this isn't worth doing just so that you can use
  1957.      EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD.  */
  1958.   char *p;
  1959. #ifndef SETUP_SYNONYM_TYPES
  1960.   /* This determines whether compatible things like `int' and `long int'
  1961.      ought to have distinct type records rather than sharing one.  */
  1962.   struct VMS_DBG_Symbol *spnt2;
  1963.  
  1964.   /* first check whether this type has already been seen by another name */
  1965.   for (spnt2 = VMS_Symbol_type_list; spnt2; spnt2 = spnt2->next)
  1966.     if (spnt2 != spnt && spnt2->VMS_type == spnt->VMS_type)
  1967.       {
  1968.     spnt->struc_numb = spnt2->struc_numb;
  1969.     return;
  1970.       }
  1971. #endif
  1972.  
  1973.   /* `structure number' doesn't really mean `structure'; it means an index
  1974.      into a linker maintained set of saved locations which can be referenced
  1975.      again later.  */
  1976.   spnt->struc_numb = ++structure_count;
  1977.   VMS_Def_Struct (spnt->struc_numb);    /* remember where this type lives */
  1978.   /* define the simple scalar type */
  1979.   Local[Lpnt++] = 6 + strlen (symbol_name) + 2;    /* rec.len */
  1980.   Local[Lpnt++] = DST_K_TYPSPEC;    /* rec.typ==type specification */
  1981.   Local[Lpnt++] = strlen (symbol_name) + 2;
  1982.   Local[Lpnt++] = '_';            /* prefix name with "__" */
  1983.   Local[Lpnt++] = '_';
  1984.   for (p = symbol_name; *p; p++)
  1985.     Local[Lpnt++] = *p == ' ' ? '_' : *p;
  1986.   COPY_SHORT(&Local[Lpnt], 2);        /* typ.len==2 */
  1987.   Lpnt += 2;
  1988.   Local[Lpnt++] = DST_K_TS_ATOM;    /* typ.kind is simple type */
  1989.   Local[Lpnt++] = spnt->VMS_type;    /* typ.type */
  1990.   VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
  1991.   Lpnt = 0;
  1992. #endif    /* SETUP_BASIC_TYPES */
  1993. }
  1994.  
  1995. /* This routine generates a symbol definition for a C symbol for the debugger.
  1996.  * It takes a psect and offset for global symbols; if psect < 0, then this is
  1997.  * a local variable and the offset is relative to FP.  In this case it can
  1998.  * be either a variable (Offset < 0) or a parameter (Offset > 0).
  1999.  */
  2000. static
  2001. VMS_DBG_record (spnt, Psect, Offset, Name)
  2002.      struct VMS_DBG_Symbol *spnt;
  2003.      int Psect;
  2004.      int Offset;
  2005.      char *Name;
  2006. {
  2007.   char *pnt;
  2008.   char *Name_pnt;
  2009.   int j;
  2010.   int len;
  2011.   int i = 0;
  2012.  
  2013.   Name_pnt = fix_name (Name);    /* if there are bad characters in name, convert them */
  2014.   len = strlen(Name_pnt);
  2015.   if (Psect < 0)
  2016.     {                /* this is a local variable, referenced to SP */
  2017.       Local[i++] = 7 + len;
  2018.       Local[i++] = spnt->VMS_type;
  2019.       Local[i++] = (Offset > 0) ? DBG_C_FUNCTION_PARAM : DBG_C_LOCAL_SYM;
  2020.       COPY_LONG (&Local[i], Offset);
  2021.       i += 4;
  2022.     }
  2023.   else
  2024.     {
  2025.       Local[i++] = 7 + len;
  2026.       Local[i++] = spnt->VMS_type;
  2027.       Local[i++] = DST_K_VALKIND_ADDR;
  2028.       VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
  2029.       i = 0;
  2030.       VMS_Set_Data (Psect, Offset, OBJ_S_C_DBG, 0);
  2031.     }
  2032.   Local[i++] = len;
  2033.   while (*Name_pnt != '\0')
  2034.     Local[i++] = *Name_pnt++;
  2035.   VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
  2036.   if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
  2037.     generate_suffix (spnt, 0);
  2038. }
  2039.  
  2040.  
  2041. /* This routine parses the stabs entries in order to make the definition
  2042.  * for the debugger of local symbols and function parameters
  2043.  */
  2044. static int
  2045. VMS_local_stab_Parse (sp)
  2046.      symbolS *sp;
  2047. {
  2048.   char *pnt;
  2049.   char *pnt1;
  2050.   char *str;
  2051.   struct VMS_DBG_Symbol *spnt;
  2052.   struct VMS_Symbol *vsp;
  2053.   int dbx_type;
  2054.   dbx_type = 0;
  2055.   str = S_GET_NAME (sp);
  2056.   pnt = (char *) strchr (str, ':');
  2057.   if (pnt == (char *) NULL)
  2058.     return;            /* no colon present */
  2059.   pnt1 = pnt++;            /* save this for later, and skip colon */
  2060.   if (*pnt == 'c')
  2061.     return 0;            /* ignore static constants */
  2062. /* there is one little catch that we must be aware of.  Sometimes function
  2063.  * parameters are optimized into registers, and the compiler, in its infiite
  2064.  * wisdom outputs stabs records for *both*.  In general we want to use the
  2065.  * register if it is present, so we must search the rest of the symbols for
  2066.  * this function to see if this parameter is assigned to a register.
  2067.  */
  2068.   {
  2069.     char *str1;
  2070.     char *pnt2;
  2071.     symbolS *sp1;
  2072.     if (*pnt == 'p')
  2073.       {
  2074.     for (sp1 = symbol_next (sp); sp1; sp1 = symbol_next (sp1))
  2075.       {
  2076.         if (!S_IS_DEBUG (sp1))
  2077.           continue;
  2078.         if (S_GET_RAW_TYPE (sp1) == N_FUN)
  2079.           {
  2080.         char * pnt3=(char*) strchr (S_GET_NAME (sp1), ':') + 1;
  2081.         if (*pnt3 == 'F' || *pnt3 == 'f') break;
  2082.           }
  2083.         if (S_GET_RAW_TYPE (sp1) != N_RSYM)
  2084.           continue;
  2085.         str1 = S_GET_NAME (sp1);    /* and get the name */
  2086.         pnt2 = str;
  2087.         while (*pnt2 != ':')
  2088.           {
  2089.         if (*pnt2 != *str1)
  2090.           break;
  2091.         pnt2++;
  2092.         str1++;
  2093.           }
  2094.         if ((*str1 != ':') || (*pnt2 != ':'))
  2095.           continue;
  2096.         return;        /* they are the same!  lets skip this one */
  2097.       }            /* for */
  2098. /* first find the dbx symbol type from list, and then find VMS type */
  2099.     pnt++;            /* skip p in case no register */
  2100.       }            /* if */
  2101.   }                /* p block */
  2102.   pnt = cvt_integer (pnt, &dbx_type);
  2103.   spnt = find_symbol (dbx_type);
  2104.   if (!spnt)
  2105.     return 0;            /*Dunno what this is*/
  2106.   *pnt1 = '\0';
  2107.   VMS_DBG_record (spnt, -1, S_GET_VALUE (sp), str);
  2108.   *pnt1 = ':';            /* and restore the string */
  2109.   return 1;
  2110. }
  2111.  
  2112. /* This routine parses a stabs entry to find the information required to define
  2113.  * a variable.  It is used for global and static variables.
  2114.  * Basically we need to know the address of the symbol.  With older versions
  2115.  * of the compiler, const symbols are
  2116.  * treated differently, in that if they are global they are written into the
  2117.  * text psect.  The global symbol entry for such a const is actually written
  2118.  * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
  2119.  * of psects, we must search the entry points as well.  static consts are even
  2120.  * harder, since they are never assigned a memory address.  The compiler passes
  2121.  * a stab to tell us the value, but I am not sure what to do with it.
  2122.  */
  2123.  
  2124. static
  2125. VMS_stab_parse (sp, expected_type, type1, type2, Text_Psect)
  2126.      symbolS *sp;
  2127.      char expected_type;
  2128.      int type1, type2, Text_Psect;
  2129. {
  2130.   char *pnt;
  2131.   char *pnt1;
  2132.   char *str;
  2133.   symbolS *sp1;
  2134.   struct VMS_DBG_Symbol *spnt;
  2135.   struct VMS_Symbol *vsp;
  2136.   int dbx_type;
  2137.   dbx_type = 0;
  2138.   str = S_GET_NAME (sp);
  2139.   pnt = (char *) strchr (str, ':');
  2140.   if (pnt == (char *) NULL)
  2141.     return;            /* no colon present */
  2142.   pnt1 = pnt;            /* save this for later*/
  2143.   pnt++;
  2144.   if (*pnt == expected_type)
  2145.     {
  2146.       pnt = cvt_integer (pnt + 1, &dbx_type);
  2147.       spnt = find_symbol (dbx_type);
  2148.       if (spnt == (struct VMS_DBG_Symbol *) NULL)
  2149.     return 0;        /*Dunno what this is*/
  2150. /* now we need to search the symbol table to find the psect and offset for
  2151.  * this variable.
  2152.  */
  2153.       *pnt1 = '\0';
  2154.       vsp = VMS_Symbols;
  2155.       while (vsp != (struct VMS_Symbol *) NULL)
  2156.     {
  2157.       pnt = S_GET_NAME (vsp->Symbol);
  2158.       if (pnt != (char *) NULL)
  2159.         if (*pnt++ == '_')
  2160. /* make sure name is the same, and make sure correct symbol type */
  2161.           if ((strlen (pnt) == strlen (str)) && (strcmp (pnt, str) == 0)
  2162.           && ((S_GET_RAW_TYPE (vsp->Symbol) == type1) ||
  2163.               (S_GET_RAW_TYPE (vsp->Symbol) == type2)))
  2164.         break;
  2165.       vsp = vsp->Next;
  2166.     }
  2167.       if (vsp != (struct VMS_Symbol *) NULL)
  2168.     {
  2169.       VMS_DBG_record (spnt, vsp->Psect_Index, vsp->Psect_Offset, str);
  2170.       *pnt1 = ':';        /* and restore the string */
  2171.       return 1;
  2172.     }
  2173. /* the symbol was not in the symbol list, but it may be an "entry point"
  2174.    if it was a constant */
  2175.       for (sp1 = symbol_rootP; sp1; sp1 = symbol_next (sp1))
  2176.     {
  2177.       /*
  2178.        *    Dispatch on STAB type
  2179.        */
  2180.       if (S_IS_DEBUG (sp1) || (S_GET_TYPE (sp1) != N_TEXT))
  2181.         continue;
  2182.       pnt = S_GET_NAME (sp1);
  2183.       if (*pnt == '_')
  2184.         pnt++;
  2185.       if (strcmp (pnt, str) == 0)
  2186.         {
  2187.           if (!gave_compiler_message && expected_type == 'G')
  2188.         {
  2189.           printf ("***Warning - the assembly code generated by the compiler has placed\n");
  2190.           printf ("global constant(s) in the text psect.  These will not be available to\n");
  2191.           printf ("other modules, since this is not the correct way to handle this. You\n");
  2192.           printf ("have two options: 1) get a patched compiler that does not put global\n");
  2193.           printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
  2194.           printf ("definitions of global variables in your source module(s).  Don't say\n");
  2195.           printf ("I didn't warn you!");
  2196.           gave_compiler_message = 1;
  2197.         }
  2198.           VMS_DBG_record (spnt,
  2199.                   Text_Psect,
  2200.                   S_GET_VALUE (sp1),
  2201.                   str);
  2202.           *pnt1 = ':';
  2203.           *S_GET_NAME (sp1) = 'L';
  2204.           /* fool assembler to not output this
  2205.            * as a routine in the TBT */
  2206.           return 1;
  2207.         }
  2208.     }
  2209.     }
  2210.   *pnt1 = ':';            /* and restore the string */
  2211.   return 0;
  2212. }
  2213.  
  2214. static
  2215. VMS_GSYM_Parse (sp, Text_Psect)
  2216.      symbolS *sp;
  2217.      int Text_Psect;
  2218. {                /* Global variables */
  2219.   VMS_stab_parse (sp, 'G', (N_UNDF | N_EXT), (N_DATA | N_EXT), Text_Psect);
  2220. }
  2221.  
  2222.  
  2223. static
  2224. VMS_LCSYM_Parse (sp, Text_Psect)
  2225.      symbolS *sp;
  2226.      int Text_Psect;
  2227. {                /* Static symbols - uninitialized */
  2228.   VMS_stab_parse (sp, 'S', N_BSS, -1, Text_Psect);
  2229. }
  2230.  
  2231. static
  2232. VMS_STSYM_Parse (sp, Text_Psect)
  2233.      symbolS *sp;
  2234.      int Text_Psect;
  2235. {                /* Static symbols - initialized */
  2236.   VMS_stab_parse (sp, 'S', N_DATA, -1, Text_Psect);
  2237. }
  2238.  
  2239.  
  2240. /* for register symbols, we must figure out what range of addresses within the
  2241.  * psect are valid. We will use the brackets in the stab directives to give us
  2242.  * guidance as to the PC range that this variable is in scope.  I am still not
  2243.  * completely comfortable with this but as I learn more, I seem to get a better
  2244.  * handle on what is going on.
  2245.  * Caveat Emptor.
  2246.  */
  2247. static
  2248. VMS_RSYM_Parse (sp, Current_Routine, Text_Psect)
  2249.      symbolS *sp, *Current_Routine;
  2250.      int Text_Psect;
  2251. {
  2252.   char *pnt;
  2253.   char *pnt1;
  2254.   char *str;
  2255.   int dbx_type;
  2256.   struct VMS_DBG_Symbol *spnt;
  2257.   int j;
  2258.   int len;
  2259.   int i = 0;
  2260.   int bcnt = 0;
  2261.   int Min_Offset = -1;        /* min PC of validity */
  2262.   int Max_Offset = 0;        /* max PC of validity */
  2263.   symbolS *symbolP;
  2264.  
  2265.   for (symbolP = sp; symbolP; symbolP = symbol_next (symbolP))
  2266.     {
  2267.       /*
  2268.        *    Dispatch on STAB type
  2269.        */
  2270.       switch (S_GET_RAW_TYPE (symbolP))
  2271.     {
  2272.     case N_LBRAC:
  2273.       if (bcnt++ == 0)
  2274.         Min_Offset = S_GET_VALUE (symbolP);
  2275.       break;
  2276.     case N_RBRAC:
  2277.       if (--bcnt == 0)
  2278.         Max_Offset =
  2279.           S_GET_VALUE (symbolP) - 1;
  2280.       break;
  2281.     }
  2282.       if ((Min_Offset != -1) && (bcnt == 0))
  2283.     break;
  2284.       if (S_GET_RAW_TYPE (symbolP) == N_FUN)
  2285.     {
  2286.       pnt=(char*) strchr (S_GET_NAME (symbolP), ':') + 1;
  2287.       if (*pnt == 'F' || *pnt == 'f') break;
  2288.     }
  2289.     }
  2290. /* check to see that the addresses were defined.  If not, then there were no
  2291.  * brackets in the function, and we must try to search for the next function
  2292.  * Since functions can be in any order, we should search all of the symbol list
  2293.  * to find the correct ending address. */
  2294.   if (Min_Offset == -1)
  2295.     {
  2296.       int Max_Source_Offset;
  2297.       int This_Offset;
  2298.       Min_Offset = S_GET_VALUE (sp);
  2299.       for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  2300.     {
  2301.       /*
  2302.        *    Dispatch on STAB type
  2303.        */
  2304.       This_Offset = S_GET_VALUE (symbolP);
  2305.       switch (S_GET_RAW_TYPE (symbolP))
  2306.         {
  2307.         case N_TEXT | N_EXT:
  2308.           if ((This_Offset > Min_Offset) && (This_Offset < Max_Offset))
  2309.         Max_Offset = This_Offset;
  2310.           break;
  2311.         case N_SLINE:
  2312.           if (This_Offset > Max_Source_Offset)
  2313.         Max_Source_Offset = This_Offset;
  2314.         }
  2315.     }
  2316. /* if this is the last routine, then we use the PC of the last source line
  2317.  * as a marker of the max PC for which this reg is valid */
  2318.       if (Max_Offset == 0x7fffffff)
  2319.     Max_Offset = Max_Source_Offset;
  2320.     }
  2321.   dbx_type = 0;
  2322.   str = S_GET_NAME (sp);
  2323.   pnt = (char *) strchr (str, ':');
  2324.   if (pnt == (char *) NULL)
  2325.     return;            /* no colon present */
  2326.   pnt1 = pnt;            /* save this for later*/
  2327.   pnt++;
  2328.   if (*pnt != 'r')
  2329.     return 0;
  2330.   pnt = cvt_integer (pnt + 1, &dbx_type);
  2331.   spnt = find_symbol (dbx_type);
  2332.   if (!spnt)
  2333.     return 0;            /*Dunno what this is yet*/
  2334.   *pnt1 = '\0';
  2335.   pnt = fix_name (S_GET_NAME (sp));    /* if there are bad characters in name, convert them */
  2336.   len = strlen(pnt);
  2337.   Local[i++] = 25 + len;
  2338.   Local[i++] = spnt->VMS_type;
  2339.   Local[i++] = DST_K_VFLAGS_TVS;    /* trailing value specified */
  2340.   COPY_LONG(&Local[i], 1 + len);    /* relative offset, beyond name */
  2341.   i += 4;
  2342.   Local[i++] = len;            /* name length (ascic prefix) */
  2343.   while (*pnt != '\0')
  2344.     Local[i++] = *pnt++;
  2345.   Local[i++] = DST_K_VS_FOLLOWS;    /* value specification follows */
  2346.   COPY_SHORT(&Local[i], 15);        /* length of rest of record */
  2347.   i += 2;
  2348.   Local[i++] = DST_K_VS_ALLOC_SPLIT;    /* split lifetime */
  2349.   Local[i++] = 1;            /* one binding follows */
  2350.   VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
  2351.   i = 0;
  2352.   VMS_Set_Data (Text_Psect, Min_Offset, OBJ_S_C_DBG, 1);
  2353.   VMS_Set_Data (Text_Psect, Max_Offset, OBJ_S_C_DBG, 1);
  2354.   Local[i++] = DST_K_VALKIND_REG;        /* nested value spec */
  2355.   COPY_LONG(&Local[i], S_GET_VALUE (sp));
  2356.   i += 4;
  2357.   VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
  2358.   *pnt1 = ':';
  2359.   if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
  2360.     generate_suffix (spnt, 0);
  2361. }
  2362.  
  2363. /* this function examines a structure definition, checking all of the elements
  2364.  * to make sure that all of them are fully defined.  The only thing that we
  2365.  * kick out are arrays of undefined structs, since we do not know how big
  2366.  * they are.  All others we can handle with a normal forward reference.
  2367.  */
  2368. static int
  2369. forward_reference (pnt)
  2370.      char *pnt;
  2371. {
  2372.   int i;
  2373.   struct VMS_DBG_Symbol *spnt;
  2374.   struct VMS_DBG_Symbol *spnt1;
  2375.   pnt = cvt_integer (pnt + 1, &i);
  2376.   if (*pnt == ';')
  2377.     return 0;            /* no forward references */
  2378.   do
  2379.     {
  2380.       pnt = (char *) strchr (pnt, ':');
  2381.       pnt = cvt_integer (pnt + 1, &i);
  2382.       spnt = find_symbol (i);
  2383.       if(spnt != (struct VMS_DBG_Symbol*) NULL) {
  2384.     while((spnt->advanced == POINTER) || (spnt->advanced == ARRAY))
  2385.     {
  2386.       i = spnt->type2;
  2387.       spnt1 = find_symbol (spnt->type2);
  2388.       if ((spnt->advanced == ARRAY) &&
  2389.           (spnt1 == (struct VMS_DBG_Symbol *) NULL))
  2390.         return 1;
  2391.       if (spnt1 == (struct VMS_DBG_Symbol *) NULL)
  2392.         break;
  2393.       spnt = spnt1;
  2394.     }
  2395.       }
  2396.       pnt = cvt_integer (pnt + 1, &i);
  2397.       pnt = cvt_integer (pnt + 1, &i);
  2398.   } while (*++pnt != ';');
  2399.   return 0;            /* no forward refences found */
  2400. }
  2401.  
  2402. /* Used to check a single element of a structure on the final pass*/
  2403.  
  2404. static int
  2405. final_forward_reference (spnt)
  2406.   struct VMS_DBG_Symbol *spnt;
  2407. {
  2408.   struct VMS_DBG_Symbol *spnt1;
  2409.  
  2410.   while (spnt && (spnt->advanced == POINTER || spnt->advanced == ARRAY))
  2411.     {
  2412.       spnt1 = find_symbol(spnt->type2);
  2413.       if (spnt->advanced == ARRAY && !spnt1) return 1;
  2414.       spnt = spnt1;
  2415.     }
  2416.   return 0;    /* no forward refences found */
  2417. }
  2418.  
  2419. /* This routine parses the stabs directives to find any definitions of dbx type
  2420.  * numbers.  It makes a note of all of them, creating a structure element
  2421.  * of VMS_DBG_Symbol that describes it.  This also generates the info for the
  2422.  * debugger that describes the struct/union/enum, so that further references
  2423.  * to these data types will be by number
  2424.  *     We have to process pointers right away, since there can be references
  2425.  * to them later in the same stabs directive.  We cannot have forward
  2426.  * references to pointers, (but we can have a forward reference to a pointer to
  2427.  * a structure/enum/union) and this is why we process them immediately.
  2428.  * After we process the pointer, then we search for defs that are nested even
  2429.  * deeper.
  2430.  * 8/15/92: We have to process arrays right away too, because there can
  2431.  * be multiple references to identical array types in one structure
  2432.  * definition, and only the first one has the definition.  (We tend to
  2433.  * parse from the back going forward.
  2434.  */
  2435. static int
  2436. VMS_typedef_parse (str)
  2437.      char *str;
  2438. {
  2439.   char *pnt;
  2440.   char *pnt1;
  2441.   char *pnt2;
  2442.   int i;
  2443.   int dtype;
  2444.   struct forward_ref *fpnt;
  2445.   int i1, i2, i3, len;
  2446.   int convert_integer;
  2447.   struct VMS_DBG_Symbol *spnt;
  2448.   struct VMS_DBG_Symbol *spnt1;
  2449.  
  2450. /* check for any nested def's */
  2451.   pnt = (char *) strchr (str + 1, '=');
  2452.   if ((pnt != (char *) NULL) && (*(str + 1) != '*')
  2453.     && (str[1] != 'a' || str[2] != 'r'))
  2454.     if (VMS_typedef_parse (pnt) == 1)
  2455.       return 1;
  2456. /* now find dbx_type of entry */
  2457.   pnt = str - 1;
  2458.   if (*pnt == 'c')
  2459.     {                /* check for static constants */
  2460.       *str = '\0';        /* for now we ignore them */
  2461.       return 0;
  2462.     }
  2463.   while ((*pnt <= '9') && (*pnt >= '0'))
  2464.     pnt--;
  2465.   pnt++;            /* and get back to the number */
  2466.   cvt_integer (pnt, &i1);
  2467.   spnt = find_symbol (i1);
  2468. /* first we see if this has been defined already, due to a forward reference*/
  2469.   if (!spnt)
  2470.     {
  2471.       spnt = (struct VMS_DBG_Symbol *) xmalloc (sizeof (struct VMS_DBG_Symbol));
  2472.       spnt->next = VMS_Symbol_type_list;
  2473.       VMS_Symbol_type_list = spnt;
  2474.       spnt->dbx_type = i1;    /* and save the type */
  2475.       spnt->type2 = spnt->VMS_type = spnt->data_size = 0;
  2476.       spnt->index_min = spnt->index_max = spnt->struc_numb = 0;
  2477.     }
  2478. /* for structs and unions, do a partial parse, otherwise we sometimes get
  2479.  * circular definitions that are impossible to resolve. We read enough info
  2480.  * so that any reference to this type has enough info to be resolved
  2481.  */
  2482.   pnt = str + 1;        /* point to character past equal sign */
  2483.   if ((*pnt == 'u') || (*pnt == 's'))
  2484.     {
  2485.     }
  2486.   if ((*pnt <= '9') && (*pnt >= '0'))
  2487.     {
  2488.       if (type_check ("void"))
  2489.     {            /* this is the void symbol */
  2490.       *str = '\0';
  2491.       spnt->advanced = VOID;
  2492.       return 0;
  2493.     }
  2494.       if (type_check ("unknown type"))
  2495.     {
  2496.       *str = '\0';
  2497.       spnt->advanced = UNKNOWN;
  2498.       return 0;
  2499.     }
  2500.       pnt1 = cvt_integer(pnt,&i1);
  2501.       if(i1 != spnt->dbx_type)
  2502.     {
  2503.       spnt->advanced = ALIAS;
  2504.       spnt->type2 = i1;
  2505.       strcpy(str, pnt1);
  2506.       return 0;
  2507.     }
  2508.       printf ("gcc-as warning(debugger output):");
  2509.       printf (" %d is an unknown untyped variable.\n", spnt->dbx_type);
  2510.       return 1;            /* do not know what this is */
  2511.     }
  2512. /* now define this module*/
  2513.   pnt = str + 1;        /* point to character past equal sign */
  2514.   switch (*pnt)
  2515.     {
  2516.     case 'r':
  2517.       spnt->advanced = BASIC;
  2518.       if (type_check ("int"))
  2519.     {
  2520.       spnt->VMS_type = DBG_S_C_SLINT;
  2521.       spnt->data_size = 4;
  2522.     }
  2523.       else if (type_check ("long int"))
  2524.     {
  2525.       spnt->VMS_type = DBG_S_C_SLINT;
  2526.       spnt->data_size = 4;
  2527.     }
  2528.       else if (type_check ("unsigned int"))
  2529.     {
  2530.       spnt->VMS_type = DBG_S_C_ULINT;
  2531.       spnt->data_size = 4;
  2532.     }
  2533.       else if (type_check ("long unsigned int"))
  2534.     {
  2535.       spnt->VMS_type = DBG_S_C_ULINT;
  2536.       spnt->data_size = 4;
  2537.     }
  2538.       else if (type_check ("short int"))
  2539.     {
  2540.       spnt->VMS_type = DBG_S_C_SSINT;
  2541.       spnt->data_size = 2;
  2542.     }
  2543.       else if (type_check ("short unsigned int"))
  2544.     {
  2545.       spnt->VMS_type = DBG_S_C_USINT;
  2546.       spnt->data_size = 2;
  2547.     }
  2548.       else if (type_check ("char"))
  2549.     {
  2550.       spnt->VMS_type = DBG_S_C_SCHAR;
  2551.       spnt->data_size = 1;
  2552.     }
  2553.       else if (type_check ("signed char"))
  2554.     {
  2555.       spnt->VMS_type = DBG_S_C_SCHAR;
  2556.       spnt->data_size = 1;
  2557.     }
  2558.       else if (type_check ("unsigned char"))
  2559.     {
  2560.       spnt->VMS_type = DBG_S_C_UCHAR;
  2561.       spnt->data_size = 1;
  2562.     }
  2563.       else if (type_check ("float"))
  2564.     {
  2565.       spnt->VMS_type = DBG_S_C_REAL4;
  2566.       spnt->data_size = 4;
  2567.     }
  2568.       else if (type_check ("double"))
  2569.     {
  2570.       spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
  2571.       spnt->data_size = 8;
  2572.     }
  2573.       else if (type_check ("long double"))
  2574.     {
  2575.       /* same as double, at least for now */
  2576.       spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
  2577.       spnt->data_size = 8;
  2578.     }
  2579.       else if (type_check ("long long int"))
  2580.     {
  2581.       spnt->VMS_type = DBG_S_C_SQUAD;    /* signed quadword */
  2582.       spnt->data_size = 8;
  2583.     }
  2584.       else if (type_check ("long long unsigned int"))
  2585.     {
  2586.       spnt->VMS_type = DBG_S_C_UQUAD;    /* unsigned quadword */
  2587.       spnt->data_size = 8;
  2588.     }
  2589.       else if (type_check ("complex float"))
  2590.     {
  2591.       spnt->VMS_type = DBG_S_C_COMPLX4;
  2592.       spnt->data_size = 2 * 4;
  2593.     }
  2594.       else if (type_check ("complex double"))
  2595.     {
  2596.       spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
  2597.       spnt->data_size = 2 * 8;
  2598.     }
  2599.       else if (type_check ("complex long double"))
  2600.     {
  2601.       /* same as complex double, at least for now */
  2602.       spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
  2603.       spnt->data_size = 2 * 8;
  2604.     }
  2605.       else
  2606.     {
  2607.       /*    [pr]
  2608.        * Shouldn't get here, but if we do, something
  2609.        * more substantial ought to be done...
  2610.        */
  2611.       spnt->VMS_type = 0;
  2612.       spnt->data_size = 0;
  2613.     }
  2614.       if (spnt->VMS_type != 0)
  2615.     setup_basic_type(spnt);
  2616.       pnt1 = (char *) strchr (str, ';') + 1;
  2617.       break;
  2618.     case 's':
  2619.     case 'u':
  2620.       spnt->advanced = (*pnt == 's') ? STRUCT : UNION;
  2621.       spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
  2622.       pnt1 = cvt_integer (pnt + 1, &spnt->data_size);
  2623.       if (!final_pass && forward_reference(pnt))
  2624.     {
  2625.       spnt->struc_numb = -1;
  2626.       return 1;
  2627.     }
  2628.       spnt->struc_numb = ++structure_count;
  2629.       pnt1--;
  2630.       pnt = get_struct_name (str);
  2631.       VMS_Def_Struct (spnt->struc_numb);
  2632.       i = 0;
  2633.       for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
  2634.     if (fpnt->dbx_type == spnt->dbx_type)
  2635.       {
  2636.         fpnt->resolved = 'Y';
  2637.         VMS_Set_Struct (fpnt->struc_numb);
  2638.         VMS_Store_Struct (spnt->struc_numb);
  2639.         i++;
  2640.       }
  2641.       if (i > 0)
  2642.     VMS_Set_Struct (spnt->struc_numb);
  2643.       i = 0;
  2644.       Local[i++] = 11 + strlen (pnt);
  2645.       Local[i++] = DBG_S_C_STRUCT_START;
  2646.       Local[i++] = DST_K_VFLAGS_NOVAL;    /* structure definition only */
  2647.       COPY_LONG(&Local[i], 0L);        /* hence value is unused */
  2648.       i += 4;
  2649.       Local[i++] = strlen (pnt);
  2650.       pnt2 = pnt;
  2651.       while (*pnt2 != '\0')
  2652.     Local[i++] = *pnt2++;
  2653.       i2 = spnt->data_size * 8;    /* number of bits */
  2654.       COPY_LONG(&Local[i], i2);
  2655.       i += 4;
  2656.       VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
  2657.       i = 0;
  2658.       if (pnt != symbol_name)
  2659.     {
  2660.       pnt += strlen (pnt);
  2661.       *pnt = ':';
  2662.     }            /* replace colon for later */
  2663.       while (*++pnt1 != ';')
  2664.     {
  2665.       pnt = (char *) strchr (pnt1, ':');
  2666.       *pnt = '\0';
  2667.       pnt2 = pnt1;
  2668.       pnt1 = cvt_integer (pnt + 1, &dtype);
  2669.       pnt1 = cvt_integer (pnt1 + 1, &i2);
  2670.       pnt1 = cvt_integer (pnt1 + 1, &i3);
  2671.       spnt1 = find_symbol (dtype);
  2672.       len = strlen (pnt2);
  2673.       if (spnt1 && (spnt1->advanced == BASIC || spnt1->advanced == ENUM)
  2674.           && ((i3 != spnt1->data_size * 8) || (i2 % 8 != 0)))
  2675.         {            /* bitfield */
  2676.           if (USE_BITSTRING_DESCRIPTOR (spnt1))
  2677.         {
  2678.           /* This uses a type descriptor, which doesn't work if
  2679.              the enclosing structure has been placed in a register.
  2680.              Also, enum bitfields degenerate to simple integers.  */
  2681.           int unsigned_type = (spnt1->VMS_type == DBG_S_C_ULINT
  2682.                     || spnt1->VMS_type == DBG_S_C_USINT
  2683.                     || spnt1->VMS_type == DBG_S_C_UCHAR
  2684.                     || spnt1->VMS_type == DBG_S_C_UQUAD
  2685.                     || spnt1->advanced == ENUM); /* (approximate) */
  2686.           Apoint = 0;
  2687.           push (19 + len, 1);
  2688.           push (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
  2689.           push (DST_K_VFLAGS_DSC, 1); /* specified by descriptor */
  2690.           push (1 + len, 4);    /* relative offset to descriptor */
  2691.           push (len, 1);        /* length byte (ascic prefix) */
  2692.           while (*pnt2 != '\0')    /* name bytes */
  2693.             push (*pnt2++, 1);
  2694.           push (i3, 2);        /* dsc length == size of bitfield */
  2695.                     /* dsc type == un?signed bitfield */
  2696.           push (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
  2697.           push (DSC_K_CLASS_UBS, 1); /* dsc class == unaligned bitstring */
  2698.           push (0x00, 4);        /* dsc pointer == zeroes */
  2699.           push (i2, 4);        /* start position */
  2700.           VMS_Store_Immediate_Data (Asuffix, Apoint, OBJ_S_C_DBG);
  2701.           Apoint = 0;
  2702.         }
  2703.           else
  2704.         {
  2705.           /* Use a "novel length" type specification, which works
  2706.              right for register structures and for enum bitfields
  2707.              but results in larger object modules.  */
  2708.           Local[i++] = 7 + len;
  2709.           Local[i++] = DBG_S_C_ADVANCED_TYPE;    /* type spec follows */
  2710.           Local[i++] = DBG_S_C_STRUCT_ITEM;    /* value is a bit offset */
  2711.           COPY_LONG (&Local[i], i2);        /* bit offset */
  2712.           i += 4;
  2713.           Local[i++] = strlen (pnt2);
  2714.           while (*pnt2 != '\0')
  2715.             Local[i++] = *pnt2++;
  2716.           VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
  2717.           i = 0;
  2718.           bitfield_suffix (spnt1, i3);
  2719.          }
  2720.         }
  2721.       else
  2722.         {            /* not a bitfield */
  2723.           /* check if this is a forward reference */
  2724.           if(final_pass && final_forward_reference(spnt1))
  2725.         {
  2726.           printf("gcc-as warning(debugger output):");
  2727.           printf("structure element `%s' has undefined type\n",pnt2);
  2728.           continue;
  2729.         }
  2730.           Local[i++] = 7 + len;
  2731.           Local[i++] = spnt1 ? spnt1->VMS_type : DBG_S_C_ADVANCED_TYPE;
  2732.           Local[i++] = DBG_S_C_STRUCT_ITEM;
  2733.           COPY_LONG (&Local[i], i2);        /* bit offset */
  2734.           i += 4;
  2735.           Local[i++] = strlen (pnt2);
  2736.           while (*pnt2 != '\0')
  2737.         Local[i++] = *pnt2++;
  2738.           VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
  2739.           i = 0;
  2740.           if (!spnt1)
  2741.         generate_suffix (spnt1, dtype);
  2742.           else if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
  2743.         generate_suffix (spnt1, 0);
  2744.         }
  2745.     }
  2746.       pnt1++;
  2747.       Local[i++] = 0x01;    /* length byte */
  2748.       Local[i++] = DBG_S_C_STRUCT_END;
  2749.       VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
  2750.       i = 0;
  2751.       break;
  2752.     case 'e':
  2753.       spnt->advanced = ENUM;
  2754.       spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
  2755.       spnt->struc_numb = ++structure_count;
  2756.       spnt->data_size = 4;
  2757.       VMS_Def_Struct (spnt->struc_numb);
  2758.       i = 0;
  2759.       for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
  2760.     if (fpnt->dbx_type == spnt->dbx_type)
  2761.       {
  2762.         fpnt->resolved = 'Y';
  2763.         VMS_Set_Struct (fpnt->struc_numb);
  2764.         VMS_Store_Struct (spnt->struc_numb);
  2765.         i++;
  2766.       }
  2767.       if (i > 0)
  2768.     VMS_Set_Struct (spnt->struc_numb);
  2769.       i = 0;
  2770.       len = strlen (symbol_name);
  2771.       Local[i++] = 3 + len;
  2772.       Local[i++] = DBG_S_C_ENUM_START;
  2773.       Local[i++] = 4 * 8;        /* enum values are 32 bits */
  2774.       Local[i++] = len;
  2775.       pnt2 = symbol_name;
  2776.       while (*pnt2 != '\0')
  2777.     Local[i++] = *pnt2++;
  2778.       VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
  2779.       i = 0;
  2780.       while (*++pnt != ';')
  2781.     {
  2782.       pnt1 = (char *) strchr (pnt, ':');
  2783.       *pnt1++ = '\0';
  2784.       pnt1 = cvt_integer (pnt1, &i1);
  2785.       len = strlen (pnt);
  2786.       Local[i++] = 7 + len;
  2787.       Local[i++] = DBG_S_C_ENUM_ITEM;
  2788.       Local[i++] = DST_K_VALKIND_LITERAL;
  2789.       COPY_LONG (&Local[i], i1);
  2790.       i += 4;
  2791.       Local[i++] = len;
  2792.       pnt2 = pnt;
  2793.       while (*pnt != '\0')
  2794.         Local[i++] = *pnt++;
  2795.       VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
  2796.       i = 0;
  2797.       pnt = pnt1;        /* Skip final semicolon */
  2798.     }
  2799.       Local[i++] = 0x01;    /* len byte */
  2800.       Local[i++] = DBG_S_C_ENUM_END;
  2801.       VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
  2802.       i = 0;
  2803.       pnt1 = pnt + 1;
  2804.       break;
  2805.     case 'a':
  2806.       spnt->advanced = ARRAY;
  2807.       spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
  2808.       pnt = (char *) strchr (pnt, ';');
  2809.       if (pnt == (char *) NULL)
  2810.     return 1;
  2811.       pnt1 = cvt_integer (pnt + 1, &spnt->index_min);
  2812.       pnt1 = cvt_integer (pnt1 + 1, &spnt->index_max);
  2813.       pnt1 = cvt_integer (pnt1 + 1, &spnt->type2);
  2814.       pnt=(char*)strchr(str+1,'=');
  2815.       if((pnt != (char*) NULL)) 
  2816.     if(VMS_typedef_parse(pnt) == 1 ) return 1;
  2817.       break;
  2818.     case 'f':
  2819.       spnt->advanced = FUNCTION;
  2820.       spnt->VMS_type = DBG_S_C_FUNCTION_ADDR;
  2821.       /* this masquerades as a basic type*/
  2822.       spnt->data_size = 4;
  2823.       pnt1 = cvt_integer (pnt + 1, &spnt->type2);
  2824.       break;
  2825.     case '*':
  2826.       spnt->advanced = POINTER;
  2827.       spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
  2828.       spnt->data_size = 4;
  2829.       pnt1 = cvt_integer (pnt + 1, &spnt->type2);
  2830.       pnt = (char *) strchr (str + 1, '=');
  2831.       if ((pnt != (char *) NULL))
  2832.     if (VMS_typedef_parse (pnt) == 1)
  2833.       return 1;
  2834.       break;
  2835.     default:
  2836.       spnt->advanced = UNKNOWN;
  2837.       spnt->VMS_type = 0;
  2838.       printf ("gcc-as warning(debugger output):");
  2839.       printf (" %d is an unknown type of variable.\n", spnt->dbx_type);
  2840.       return 1;            /* unable to decipher */
  2841.     }
  2842. /* this removes the evidence of the definition so that the outer levels of
  2843. parsing do not have to worry about it */
  2844.   pnt = str;
  2845.   while (*pnt1 != '\0')
  2846.     *pnt++ = *pnt1++;
  2847.   *pnt = '\0';
  2848.   return 0;
  2849. }
  2850.  
  2851.  
  2852. /*
  2853.  * This is the root routine that parses the stabs entries for definitions.
  2854.  * it calls VMS_typedef_parse, which can in turn call itself.
  2855.  * We need to be careful, since sometimes there are forward references to
  2856.  * other symbol types, and these cannot be resolved until we have completed
  2857.  * the parse.
  2858.  *
  2859.  * Also check and see if we are using continuation stabs, if we are, then
  2860.  * paste together the entire contents of the stab before we pass it to 
  2861.  * VMS_typedef_parse.
  2862.  */
  2863. static int
  2864. VMS_LSYM_Parse ()
  2865. {
  2866.   char *pnt;
  2867.   char *pnt1;
  2868.   char *pnt2;
  2869.   char *str;
  2870.   char *parse_buffer = 0;
  2871.   char fixit[10];
  2872.   int incomplete, i, pass, incom1;
  2873.   struct VMS_DBG_Symbol *spnt;
  2874.   struct VMS_Symbol *vsp;
  2875.   struct forward_ref *fpnt;
  2876.   symbolS *sp;
  2877.   pass = 0;
  2878.   final_pass = 0;
  2879.   incomplete = 0;
  2880.   do
  2881.     {
  2882.       incom1 = incomplete;
  2883.       incomplete = 0;
  2884.       for (sp = symbol_rootP; sp; sp = symbol_next (sp))
  2885.     {
  2886.       /*
  2887.        *    Deal with STAB symbols
  2888.        */
  2889.       if (S_IS_DEBUG (sp))
  2890.         {
  2891.           /*
  2892.            *    Dispatch on STAB type
  2893.            */
  2894.           switch (S_GET_RAW_TYPE (sp))
  2895.         {
  2896.         case N_GSYM:
  2897.         case N_LCSYM:
  2898.         case N_STSYM:
  2899.         case N_PSYM:
  2900.         case N_RSYM:
  2901.         case N_LSYM:
  2902.         case N_FUN:    /*sometimes these contain typedefs*/
  2903.           str = S_GET_NAME (sp);
  2904.           symbol_name = str;
  2905.           pnt = str + strlen(str) -1;
  2906.           if (*pnt == '?')  /* Continuation stab.  */
  2907.             {
  2908.               symbolS *spnext;
  2909.               int tlen = 0;
  2910.               spnext = sp;
  2911.               do {
  2912.             tlen += strlen(str) - 1;
  2913.             spnext = symbol_next (spnext);
  2914.             str = S_GET_NAME (spnext);
  2915.             pnt = str + strlen(str) - 1;
  2916.               } while (*pnt == '?');
  2917.               tlen += strlen(str);
  2918.               parse_buffer = (char *) xmalloc (tlen + 1);
  2919.               strcpy(parse_buffer, S_GET_NAME (sp));
  2920.               pnt2 = parse_buffer + strlen(S_GET_NAME (sp)) - 1;
  2921.               *pnt2 = '\0';
  2922.               spnext = sp;
  2923.               do {
  2924.             spnext = symbol_next (spnext);
  2925.             str = S_GET_NAME (spnext);
  2926.             strcat (pnt2, S_GET_NAME (spnext));
  2927.             pnt2 +=  strlen(str) - 1;
  2928.             *str = '\0';  /* Erase this string  */
  2929.             if (*pnt2 != '?') break;
  2930.             *pnt2 = '\0';
  2931.               } while (1 == 1);
  2932.               str = parse_buffer;
  2933.               symbol_name = str;
  2934.             }
  2935.           pnt = (char *) strchr (str, ':');
  2936.           if (pnt != (char *) NULL)
  2937.             {
  2938.               *pnt = '\0';
  2939.               pnt1 = pnt + 1;
  2940.               pnt2 = (char *) strchr (pnt1, '=');
  2941.               if (pnt2 != (char *) NULL)
  2942.             incomplete += VMS_typedef_parse (pnt2);
  2943.               if (parse_buffer){
  2944.             /*  At this point the parse buffer should just contain name:nn.
  2945.                 If it does not, then we are in real trouble. Anyway, 
  2946.                 this is always shorter than the original line. */
  2947.             strcpy(S_GET_NAME (sp), parse_buffer);
  2948.             free (parse_buffer);
  2949.             parse_buffer = 0;
  2950.               }
  2951.               *pnt = ':';    /* put back colon so variable def code finds dbx_type*/
  2952.             }
  2953.           break;
  2954.         }        /*switch*/
  2955.         }            /* if */
  2956.     }            /*for*/
  2957.       pass++;
  2958. /* Make one last pass, if needed, and define whatever we can that is left */
  2959.       if(final_pass == 0 && incomplete == incom1)
  2960.         {
  2961.           final_pass = 1;
  2962.       incom1 ++;  /* Force one last pass through */
  2963.     }
  2964.   } while ((incomplete != 0) && (incomplete != incom1));
  2965.   /* repeat until all refs resolved if possible */
  2966. /*    if (pass > 1) printf(" Required %d passes\n",pass);*/
  2967.   if (incomplete != 0)
  2968.     {
  2969.       printf ("gcc-as warning(debugger output):");
  2970.       printf ("Unable to resolve %d circular references.\n", incomplete);
  2971.     }
  2972.   fpnt = f_ref_root;
  2973.   symbol_name = "\0";
  2974.   while (fpnt != (struct forward_ref *) NULL)
  2975.     {
  2976.       if (fpnt->resolved != 'Y')
  2977.     {
  2978.       if (find_symbol (fpnt->dbx_type) !=
  2979.           (struct VMS_DBG_Symbol *) NULL)
  2980.         {
  2981.           printf ("gcc-as warning(debugger output):");
  2982.           printf ("Forward reference error, dbx type %d\n",
  2983.               fpnt->dbx_type);
  2984.           break;
  2985.         }
  2986.       fixit[0] = 0;
  2987.       sprintf (&fixit[1], "%d=s4;", fpnt->dbx_type);
  2988.       pnt2 = (char *) strchr (&fixit[1], '=');
  2989.       VMS_typedef_parse (pnt2);
  2990.     }
  2991.       fpnt = fpnt->next;
  2992.     }
  2993. }
  2994.  
  2995. static
  2996. Define_Local_Symbols (s1, s2)
  2997.      symbolS *s1, *s2;
  2998. {
  2999.   symbolS *symbolP1;
  3000.   for (symbolP1 = symbol_next (s1); symbolP1 != s2; symbolP1 = symbol_next (symbolP1))
  3001.     {
  3002.       if (symbolP1 == (symbolS *) NULL)
  3003.     return;
  3004.       if (S_GET_RAW_TYPE (symbolP1) == N_FUN)
  3005.     {
  3006.       char * pnt=(char*) strchr (S_GET_NAME (symbolP1), ':') + 1;
  3007.       if (*pnt == 'F' || *pnt == 'f') break;
  3008.     }
  3009.       /*
  3010.        *    Deal with STAB symbols
  3011.        */
  3012.       if (S_IS_DEBUG (symbolP1))
  3013.     {
  3014.       /*
  3015.        *    Dispatch on STAB type
  3016.        */
  3017.       switch (S_GET_RAW_TYPE (symbolP1))
  3018.         {
  3019.         case N_LSYM:
  3020.         case N_PSYM:
  3021.           VMS_local_stab_Parse (symbolP1);
  3022.           break;
  3023.         case N_RSYM:
  3024.           VMS_RSYM_Parse (symbolP1, Current_Routine, Text_Psect);
  3025.           break;
  3026.         }            /*switch*/
  3027.     }            /* if */
  3028.     }                /* for */
  3029. }
  3030.  
  3031.  
  3032. /* This function crawls the symbol chain searching for local symbols that need
  3033.  * to be described to the debugger.  When we enter a new scope with a "{", it
  3034.  * creates a new "block", which helps the debugger keep track of which scope
  3035.  * we are currently in.
  3036.  */
  3037.  
  3038. static symbolS *
  3039. Define_Routine (symbolP, Level)
  3040.      symbolS *symbolP;
  3041.      int Level;
  3042. {
  3043.   symbolS *sstart;
  3044.   symbolS *symbolP1;
  3045.   char str[10];
  3046.   int rcount = 0;
  3047.   int Offset;
  3048.   sstart = symbolP;
  3049.   for (symbolP1 = symbol_next (symbolP); symbolP1; symbolP1 = symbol_next (symbolP1))
  3050.     {
  3051.       if (S_GET_RAW_TYPE (symbolP1) == N_FUN)
  3052.     {
  3053.       char * pnt=(char*) strchr (S_GET_NAME (symbolP1), ':') + 1;
  3054.       if (*pnt == 'F' || *pnt == 'f') break;
  3055.     }
  3056.       /*
  3057.        *    Deal with STAB symbols
  3058.        */
  3059.       if (S_IS_DEBUG (symbolP1))
  3060.     {
  3061.       /*
  3062.        *    Dispatch on STAB type
  3063.        */
  3064.       switch (S_GET_RAW_TYPE (symbolP1))
  3065.         {
  3066.         case N_LBRAC:
  3067.           if (Level != 0)
  3068.         {
  3069.           sprintf (str, "$%d", rcount++);
  3070.           VMS_TBT_Block_Begin (symbolP1, Text_Psect, str);
  3071.         }
  3072.           Offset = S_GET_VALUE (symbolP1);
  3073.           Define_Local_Symbols (sstart, symbolP1);
  3074.           symbolP1 =
  3075.         Define_Routine (symbolP1, Level + 1);
  3076.           if (Level != 0)
  3077.         VMS_TBT_Block_End (S_GET_VALUE (symbolP1) -
  3078.                    Offset);
  3079.           sstart = symbolP1;
  3080.           break;
  3081.         case N_RBRAC:
  3082.           return symbolP1;
  3083.         }            /*switch*/
  3084.     }            /* if */
  3085.     }                /* for */
  3086.   /* we end up here if there were no brackets in this function. Define
  3087. everything */
  3088.   Define_Local_Symbols (sstart, (symbolS *) 0);
  3089.   return symbolP1;
  3090. }
  3091.  
  3092.  
  3093. static
  3094. VMS_DBG_Define_Routine (symbolP, Curr_Routine, Txt_Psect)
  3095.      symbolS *symbolP;
  3096.      symbolS *Curr_Routine;
  3097.      int Txt_Psect;
  3098. {
  3099.   Current_Routine = Curr_Routine;
  3100.   Text_Psect = Txt_Psect;
  3101.   Define_Routine (symbolP, 0);
  3102. }
  3103.  
  3104.  
  3105.  
  3106.  
  3107. #ifndef VMS
  3108. #include <sys/types.h>
  3109. #include <time.h>
  3110.  
  3111. /* Manufacure a VMS like time on a unix based system. */
  3112. get_VMS_time_on_unix (Now)
  3113.      char *Now;
  3114. {
  3115.   char *pnt;
  3116.   time_t timeb;
  3117.   time (&timeb);
  3118.   pnt = ctime (&timeb);
  3119.   pnt[3] = 0;
  3120.   pnt[7] = 0;
  3121.   pnt[10] = 0;
  3122.   pnt[16] = 0;
  3123.   pnt[24] = 0;
  3124.   sprintf (Now, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
  3125. }
  3126.  
  3127. #endif /* not VMS */
  3128. /*
  3129.  *    Write the MHD (Module Header) records
  3130.  */
  3131. static
  3132. Write_VMS_MHD_Records ()
  3133. {
  3134.   register char *cp, *cp1;
  3135.   register int i;
  3136.   struct
  3137.   {
  3138.     int Size;
  3139.     char *Ptr;
  3140.   } Descriptor;
  3141.   char Module_Name[256];
  3142.   char Now[18];
  3143.  
  3144.   /*
  3145.    *    We are writing a module header record
  3146.    */
  3147.   Set_VMS_Object_File_Record (OBJ_S_C_HDR);
  3148.   /*
  3149.    *    ***************************
  3150.    *    *MAIN MODULE HEADER RECORD*
  3151.    *    ***************************
  3152.    *
  3153.    *    Store record type and header type
  3154.    */
  3155.   PUT_CHAR (OBJ_S_C_HDR);
  3156.   PUT_CHAR (MHD_S_C_MHD);
  3157.   /*
  3158.    *    Structure level is 0
  3159.    */
  3160.   PUT_CHAR (OBJ_S_C_STRLVL);
  3161.   /*
  3162.    *    Maximum record size is size of the object record buffer
  3163.    */
  3164.   PUT_SHORT (sizeof (Object_Record_Buffer));
  3165.   /*
  3166.    *    Get module name (the FILENAME part of the object file)
  3167.    */
  3168.   cp = out_file_name;
  3169.   cp1 = Module_Name;
  3170.   while (*cp)
  3171.     {
  3172.       if ((*cp == ']') || (*cp == '>') ||
  3173.       (*cp == ':') || (*cp == '/'))
  3174.     {
  3175.       cp1 = Module_Name;
  3176.       cp++;
  3177.       continue;
  3178.     }
  3179.       *cp1++ = islower (*cp) ? toupper (*cp++) : *cp++;
  3180.     }
  3181.   *cp1 = 0;
  3182.   /*
  3183.    *    Limit it to 31 characters and store in the object record
  3184.    */
  3185.   while (--cp1 >= Module_Name)
  3186.     if (*cp1 == '.')
  3187.       *cp1 = 0;
  3188.   if (strlen (Module_Name) > 31)
  3189.     {
  3190.       if (flag_hash_long_names)
  3191.     printf ("%s: Module name truncated: %s\n", myname, Module_Name);
  3192.       Module_Name[31] = 0;
  3193.     }
  3194.   PUT_COUNTED_STRING (Module_Name);
  3195.   /*
  3196.    *    Module Version is "V1.0"
  3197.    */
  3198.   PUT_COUNTED_STRING ("V1.0");
  3199.   /*
  3200.    *    Creation time is "now" (17 chars of time string)
  3201.    */
  3202. #ifndef VMS
  3203.   get_VMS_time_on_unix (&Now[0]);
  3204. #else /* VMS */
  3205.   Descriptor.Size = 17;
  3206.   Descriptor.Ptr = Now;
  3207.   sys$asctim (0, &Descriptor, 0, 0);
  3208. #endif /* VMS */
  3209.   for (i = 0; i < 17; i++)
  3210.     PUT_CHAR (Now[i]);
  3211.   /*
  3212.    *    Patch time is "never" (17 zeros)
  3213.    */
  3214.   for (i = 0; i < 17; i++)
  3215.     PUT_CHAR (0);
  3216.   /*
  3217.    *    Flush the record
  3218.    */
  3219.   Flush_VMS_Object_Record_Buffer ();
  3220.   /*
  3221.    *    *************************
  3222.    *    *LANGUAGE PROCESSOR NAME*
  3223.    *    *************************
  3224.    *
  3225.    *    Store record type and header type
  3226.    */
  3227.   PUT_CHAR (OBJ_S_C_HDR);
  3228.   PUT_CHAR (MHD_S_C_LNM);
  3229.   /*
  3230.    *    Store language processor name and version
  3231.    *    (not a counted string!)
  3232.    *
  3233.    *    This is normally supplied by the gcc driver for the command line
  3234.    *    which invokes gas.  If absent, we fall back to gas's version.
  3235.    */
  3236.   cp = compiler_version_string;
  3237.   if (cp == 0)
  3238.     {
  3239.       cp = "GNU AS  V";
  3240.       while (*cp)
  3241.     PUT_CHAR (*cp++);
  3242.       cp = GAS_VERSION;
  3243.     }
  3244.   while (*cp >= ' ')
  3245.     PUT_CHAR (*cp++);
  3246.   /*
  3247.    *    Flush the record
  3248.    */
  3249.   Flush_VMS_Object_Record_Buffer ();
  3250. }
  3251.  
  3252.  
  3253. /*
  3254.  *    Write the EOM (End Of Module) record
  3255.  */
  3256. static
  3257. Write_VMS_EOM_Record (Psect, Offset)
  3258.      int Psect;
  3259.      int Offset;
  3260. {
  3261.   /*
  3262.    *    We are writing an end-of-module record
  3263.    */
  3264.   Set_VMS_Object_File_Record (OBJ_S_C_EOM);
  3265.   /*
  3266.    *    Store record Type
  3267.    */
  3268.   PUT_CHAR (OBJ_S_C_EOM);
  3269.   /*
  3270.    *    Store the error severity (0)
  3271.    */
  3272.   PUT_CHAR (0);
  3273.   /*
  3274.    *    Store the entry point, if it exists
  3275.    */
  3276.   if (Psect >= 0)
  3277.     {
  3278.       /*
  3279.        *    Store the entry point Psect
  3280.        */
  3281.       PUT_CHAR (Psect);
  3282.       /*
  3283.        *    Store the entry point Psect offset
  3284.        */
  3285.       PUT_LONG (Offset);
  3286.     }
  3287.   /*
  3288.    *    Flush the record
  3289.    */
  3290.   Flush_VMS_Object_Record_Buffer ();
  3291. }
  3292.  
  3293.  
  3294. /* this hash routine borrowed from GNU-EMACS, and strengthened slightly  ERY*/
  3295.  
  3296. static int
  3297. hash_string (ptr)
  3298.      unsigned char *ptr;
  3299. {
  3300.   register unsigned char *p = ptr;
  3301.   register unsigned char *end = p + strlen (ptr);
  3302.   register unsigned char c;
  3303.   register int hash = 0;
  3304.  
  3305.   while (p != end)
  3306.     {
  3307.       c = *p++;
  3308.       hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
  3309.     }
  3310.   return hash;
  3311. }
  3312.  
  3313. /*
  3314.  *    Generate a Case-Hacked VMS symbol name (limited to 31 chars)
  3315.  */
  3316. static
  3317. VMS_Case_Hack_Symbol (In, Out)
  3318.      register char *In;
  3319.      register char *Out;
  3320. {
  3321.   long int init = 0;
  3322.   long int result;
  3323.   char *pnt;
  3324.   char *new_name;
  3325.   char *old_name;
  3326.   register int i;
  3327.   int destructor = 0;        /*hack to allow for case sens in a destructor*/
  3328.   int truncate = 0;
  3329.   int Case_Hack_Bits = 0;
  3330.   int Saw_Dollar = 0;
  3331.   static char Hex_Table[16] =
  3332.   {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  3333.  
  3334.   /*
  3335.    *    Kill any leading "_"
  3336.    */
  3337.   if ((In[0] == '_') && ((In[1] > '9') || (In[1] < '0')))
  3338.     In++;
  3339.  
  3340.   new_name = Out;        /* save this for later*/
  3341.  
  3342. #if barfoo            /* Dead code */
  3343.   if ((In[0] == '_') && (In[1] == '$') && (In[2] == '_'))
  3344.     destructor = 1;
  3345. #endif
  3346.  
  3347.   /* We may need to truncate the symbol, save the hash for later*/
  3348.   if (strlen (In) > 23)
  3349.     result = hash_string (In);
  3350.   /*
  3351.    *    Is there a Psect Attribute to skip??
  3352.    */
  3353.   if (HAS_PSECT_ATTRIBUTES (In))
  3354.     {
  3355.       /*
  3356.        *    Yes: Skip it
  3357.        */
  3358.       In += PSECT_ATTRIBUTES_STRING_LENGTH;
  3359.       while (*In)
  3360.     {
  3361.       if ((In[0] == '$') && (In[1] == '$'))
  3362.         {
  3363.           In += 2;
  3364.           break;
  3365.         }
  3366.       In++;
  3367.     }
  3368.     }
  3369.  
  3370.   old_name = In;
  3371. /*    if (strlen(In) > 31 && flag_hash_long_names)
  3372.         printf("%s: Symbol name truncated: %s\n",myname,In);*/
  3373.   /*
  3374.    *    Do the case conversion
  3375.    */
  3376.   i = 23;            /* Maximum of 23 chars */
  3377.   while (*In && (--i >= 0))
  3378.     {
  3379.       Case_Hack_Bits <<= 1;
  3380.       if (*In == '$')
  3381.     Saw_Dollar = 1;
  3382.       if ((destructor == 1) && (i == 21))
  3383.     Saw_Dollar = 0;
  3384.       switch (vms_name_mapping)
  3385.     {
  3386.     case 0:
  3387.       if (isupper(*In)) {
  3388.         *Out++ = *In++;
  3389.         Case_Hack_Bits |= 1;
  3390.       } else {
  3391.         *Out++ = islower(*In) ? toupper(*In++) : *In++;
  3392.       }
  3393.       break;
  3394.     case 3: *Out++ = *In++;
  3395.       break;
  3396.     case 2:
  3397.       if (islower(*In)) {
  3398.         *Out++ = *In++;
  3399.       } else {
  3400.         *Out++ = isupper(*In) ? tolower(*In++) : *In++;
  3401.       }
  3402.       break;
  3403.     }
  3404.     }
  3405.   /*
  3406.    *    If we saw a dollar sign, we don't do case hacking
  3407.    */
  3408.   if (flag_no_hash_mixed_case || Saw_Dollar)
  3409.     Case_Hack_Bits = 0;
  3410.  
  3411.   /*
  3412.    *    If we have more than 23 characters and everything is lowercase
  3413.    *    we can insert the full 31 characters
  3414.    */
  3415.   if (*In)
  3416.     {
  3417.       /*
  3418.        *    We  have more than 23 characters
  3419.        * If we must add the case hack, then we have truncated the str
  3420.        */
  3421.       pnt = Out;
  3422.       truncate = 1;
  3423.       if (Case_Hack_Bits == 0)
  3424.     {
  3425.       /*
  3426.        *    And so far they are all lower case:
  3427.        *        Check up to 8 more characters
  3428.        *        and ensure that they are lowercase
  3429.        */
  3430.       for (i = 0; (In[i] != 0) && (i < 8); i++)
  3431.         if (isupper(In[i]) && !Saw_Dollar && !flag_no_hash_mixed_case)
  3432.           break;
  3433.  
  3434.       if (In[i] == 0)
  3435.         truncate = 0;
  3436.  
  3437.       if ((i == 8) || (In[i] == 0))
  3438.         {
  3439.           /*
  3440.            *    They are:  Copy up to 31 characters
  3441.            *            to the output string
  3442.            */
  3443.           i = 8;
  3444.           while ((--i >= 0) && (*In))
  3445.         switch (vms_name_mapping){
  3446.         case 0: *Out++ = islower(*In) ?
  3447.           toupper (*In++) :
  3448.             *In++;
  3449.           break;
  3450.         case 3: *Out++ = *In++;
  3451.           break;
  3452.         case 2: *Out++ = isupper(*In) ?
  3453.           tolower(*In++) :
  3454.             *In++;
  3455.           break;
  3456.         }
  3457.         }
  3458.     }
  3459.     }
  3460.   /*
  3461.    *    If there were any uppercase characters in the name we
  3462.    *    take on the case hacking string
  3463.    */
  3464.  
  3465.   /* Old behavior for regular GNU-C compiler */
  3466.   if (!flag_hash_long_names)
  3467.     truncate = 0;
  3468.   if ((Case_Hack_Bits != 0) || (truncate == 1))
  3469.     {
  3470.       if (truncate == 0)
  3471.     {
  3472.       *Out++ = '_';
  3473.       for (i = 0; i < 6; i++)
  3474.         {
  3475.           *Out++ = Hex_Table[Case_Hack_Bits & 0xf];
  3476.           Case_Hack_Bits >>= 4;
  3477.         }
  3478.       *Out++ = 'X';
  3479.     }
  3480.       else
  3481.     {
  3482.       Out = pnt;        /*Cut back to 23 characters maximum */
  3483.       *Out++ = '_';
  3484.       for (i = 0; i < 7; i++)
  3485.         {
  3486.           init = result & 0x01f;
  3487.           if (init < 10)
  3488.         *Out++ = '0' + init;
  3489.           else
  3490.         *Out++ = 'A' + init - 10;
  3491.           result = result >> 5;
  3492.         }
  3493.     }
  3494.     }                /*Case Hack */
  3495.   /*
  3496.    *    Done
  3497.    */
  3498.   *Out = 0;
  3499.   if (truncate == 1 && flag_hash_long_names && flag_show_after_trunc)
  3500.     printf ("%s: Symbol %s replaced by %s\n", myname, old_name, new_name);
  3501. }
  3502.  
  3503.  
  3504. /*
  3505.  *    Scan a symbol name for a psect attribute specification
  3506.  */
  3507. #define GLOBALSYMBOL_BIT    0x10000
  3508. #define GLOBALVALUE_BIT        0x20000
  3509.  
  3510.  
  3511. static
  3512. VMS_Modify_Psect_Attributes (Name, Attribute_Pointer)
  3513.      char *Name;
  3514.      int *Attribute_Pointer;
  3515. {
  3516.   register int i;
  3517.   register char *cp;
  3518.   int Negate;
  3519.   static struct
  3520.   {
  3521.     char *Name;
  3522.     int Value;
  3523.   } Attributes[] =
  3524.   {
  3525.     {"PIC", GPS_S_M_PIC},
  3526.     {"LIB", GPS_S_M_LIB},
  3527.     {"OVR", GPS_S_M_OVR},
  3528.     {"REL", GPS_S_M_REL},
  3529.     {"GBL", GPS_S_M_GBL},
  3530.     {"SHR", GPS_S_M_SHR},
  3531.     {"EXE", GPS_S_M_EXE},
  3532.     {"RD", GPS_S_M_RD},
  3533.     {"WRT", GPS_S_M_WRT},
  3534.     {"VEC", GPS_S_M_VEC},
  3535.     {"GLOBALSYMBOL", GLOBALSYMBOL_BIT},
  3536.     {"GLOBALVALUE", GLOBALVALUE_BIT},
  3537.     {0, 0}
  3538.   };
  3539.  
  3540.   /*
  3541.    *    Kill leading "_"
  3542.    */
  3543.   if (*Name == '_')
  3544.     Name++;
  3545.   /*
  3546.    *    Check for a PSECT attribute list
  3547.    */
  3548.   if (!HAS_PSECT_ATTRIBUTES (Name))
  3549.     return;            /* If not, return */
  3550.   /*
  3551.    *    Skip the attribute list indicator
  3552.    */
  3553.   Name += PSECT_ATTRIBUTES_STRING_LENGTH;
  3554.   /*
  3555.    *    Process the attributes ("_" separated, "$" terminated)
  3556.    */
  3557.   while (*Name != '$')
  3558.     {
  3559.       /*
  3560.        *    Assume not negating
  3561.        */
  3562.       Negate = 0;
  3563.       /*
  3564.        *    Check for "NO"
  3565.        */
  3566.       if ((Name[0] == 'N') && (Name[1] == 'O'))
  3567.     {
  3568.       /*
  3569.        *    We are negating (and skip the NO)
  3570.        */
  3571.       Negate = 1;
  3572.       Name += 2;
  3573.     }
  3574.       /*
  3575.        *    Find the token delimiter
  3576.        */
  3577.       cp = Name;
  3578.       while (*cp && (*cp != '_') && (*cp != '$'))
  3579.     cp++;
  3580.       /*
  3581.        *    Look for the token in the attribute list
  3582.        */
  3583.       for (i = 0; Attributes[i].Name; i++)
  3584.     {
  3585.       /*
  3586.        *    If the strings match, set/clear the attr.
  3587.        */
  3588.       if (strncmp (Name, Attributes[i].Name, cp - Name) == 0)
  3589.         {
  3590.           /*
  3591.            *    Set or clear
  3592.            */
  3593.           if (Negate)
  3594.         *Attribute_Pointer &=
  3595.           ~Attributes[i].Value;
  3596.           else
  3597.         *Attribute_Pointer |=
  3598.           Attributes[i].Value;
  3599.           /*
  3600.            *    Done
  3601.            */
  3602.           break;
  3603.         }
  3604.     }
  3605.       /*
  3606.        *    Now skip the attribute
  3607.        */
  3608.       Name = cp;
  3609.       if (*Name == '_')
  3610.     Name++;
  3611.     }
  3612. }
  3613.  
  3614.  
  3615. /*
  3616.  *    Define a global symbol
  3617.  */
  3618. static
  3619. VMS_Global_Symbol_Spec (Name, Psect_Number, Psect_Offset, Defined)
  3620.      char *Name;
  3621.      int Psect_Number;
  3622.      int Psect_Offset;
  3623. {
  3624.   char Local[32];
  3625.  
  3626.   /*
  3627.    *    We are writing a GSD record
  3628.    */
  3629.   Set_VMS_Object_File_Record (OBJ_S_C_GSD);
  3630.   /*
  3631.    *    If the buffer is empty we must insert the GSD record type
  3632.    */
  3633.   if (Object_Record_Offset == 0)
  3634.     PUT_CHAR (OBJ_S_C_GSD);
  3635.   /*
  3636.    *    We are writing a Global symbol definition subrecord
  3637.    */
  3638.   if (Psect_Number <= 255)
  3639.     {
  3640.       PUT_CHAR (GSD_S_C_SYM);
  3641.     }
  3642.   else
  3643.     {
  3644.       PUT_CHAR (GSD_S_C_SYMW);
  3645.     }
  3646.   /*
  3647.    *    Data type is undefined
  3648.    */
  3649.   PUT_CHAR (0);
  3650.   /*
  3651.    *    Switch on Definition/Reference
  3652.    */
  3653.   if ((Defined & 1) != 0)
  3654.     {
  3655.       /*
  3656.        *    Definition:
  3657.        *    Flags = "RELOCATABLE" and "DEFINED" for regular symbol
  3658.        *          = "DEFINED" for globalvalue (Defined & 2 == 1)
  3659.        */
  3660.       if ((Defined & 2) == 0)
  3661.     {
  3662.       PUT_SHORT (GSY_S_M_DEF | GSY_S_M_REL);
  3663.     }
  3664.       else
  3665.     {
  3666.       PUT_SHORT (GSY_S_M_DEF);
  3667.     }
  3668.       /*
  3669.        *    Psect Number
  3670.        */
  3671.       if (Psect_Number <= 255)
  3672.     {
  3673.       PUT_CHAR (Psect_Number);
  3674.     }
  3675.       else
  3676.     {
  3677.       PUT_SHORT (Psect_Number);
  3678.     }
  3679.       /*
  3680.        *    Offset
  3681.        */
  3682.       PUT_LONG (Psect_Offset);
  3683.     }
  3684.   else
  3685.     {
  3686.       /*
  3687.        *    Reference:
  3688.        *    Flags = "RELOCATABLE" for regular symbol,
  3689.        *          = "" for globalvalue (Defined & 2 == 1)
  3690.        */
  3691.       if ((Defined & 2) == 0)
  3692.     {
  3693.       PUT_SHORT (GSY_S_M_REL);
  3694.     }
  3695.       else
  3696.     {
  3697.       PUT_SHORT (0);
  3698.     }
  3699.     }
  3700.   /*
  3701.    *    Finally, the global symbol name
  3702.    */
  3703.   VMS_Case_Hack_Symbol (Name, Local);
  3704.   PUT_COUNTED_STRING (Local);
  3705.   /*
  3706.    *    Flush the buffer if it is more than 75% full
  3707.    */
  3708.   if (Object_Record_Offset >
  3709.       (sizeof (Object_Record_Buffer) * 3 / 4))
  3710.     Flush_VMS_Object_Record_Buffer ();
  3711. }
  3712.  
  3713.  
  3714. /*
  3715.  *    Define a psect
  3716.  */
  3717. static int
  3718. VMS_Psect_Spec (Name, Size, Type, vsp)
  3719.      char *Name;
  3720.      int Size;
  3721.      char *Type;
  3722.      struct VMS_Symbol *vsp;
  3723. {
  3724.   char Local[32];
  3725.   int Psect_Attributes;
  3726.  
  3727.   /*
  3728.    *    Generate the appropriate PSECT flags given the PSECT type
  3729.    */
  3730.   if (strcmp (Type, "COMMON") == 0)
  3731.     {
  3732.       /*
  3733.        *    Common block psects are:  PIC,OVR,REL,GBL,SHR,RD,WRT
  3734.        */
  3735.       Psect_Attributes = (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL |
  3736.               GPS_S_M_SHR | GPS_S_M_RD | GPS_S_M_WRT);
  3737.     }
  3738.   else if (strcmp (Type, "CONST") == 0)
  3739.     {
  3740.       /*
  3741.        *    Common block psects are:  PIC,OVR,REL,GBL,SHR,RD
  3742.        */
  3743.       Psect_Attributes = (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL |
  3744.               GPS_S_M_SHR | GPS_S_M_RD);
  3745.     }
  3746.   else if (strcmp (Type, "DATA") == 0)
  3747.     {
  3748.       /*
  3749.        *    The Data psects are PIC,REL,RD,WRT
  3750.        */
  3751.       Psect_Attributes =
  3752.     (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD | GPS_S_M_WRT);
  3753.     }
  3754.   else if (strcmp (Type, "TEXT") == 0)
  3755.     {
  3756.       /*
  3757.        *    The Text psects are PIC,REL,SHR,EXE,RD
  3758.        */
  3759.       Psect_Attributes =
  3760.     (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_SHR |
  3761.      GPS_S_M_EXE | GPS_S_M_RD);
  3762.     }
  3763.   else
  3764.     {
  3765.       /*
  3766.        *    Error: Unknown psect type
  3767.        */
  3768.       error ("Unknown VMS psect type");
  3769.     }
  3770.   /*
  3771.    *    Modify the psect attributes according to any attribute string
  3772.    */
  3773.   if (HAS_PSECT_ATTRIBUTES (Name))
  3774.     VMS_Modify_Psect_Attributes (Name, &Psect_Attributes);
  3775.   /*
  3776.    *    Check for globalref/def/val.
  3777.    */
  3778.   if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
  3779.     {
  3780.       /*
  3781.        * globalvalue symbols were generated before. This code
  3782.        * prevents unsightly psect buildup, and makes sure that
  3783.        * fixup references are emitted correctly.
  3784.        */
  3785.       vsp->Psect_Index = -1;    /* to catch errors */
  3786.       S_GET_RAW_TYPE (vsp->Symbol) = N_UNDF;    /* make refs work */
  3787.       return 1;            /* decrement psect counter */
  3788.     }
  3789.  
  3790.   if ((Psect_Attributes & GLOBALSYMBOL_BIT) != 0)
  3791.     {
  3792.       switch (S_GET_RAW_TYPE (vsp->Symbol))
  3793.     {
  3794.     case N_UNDF | N_EXT:
  3795.       VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
  3796.                   vsp->Psect_Offset, 0);
  3797.       vsp->Psect_Index = -1;
  3798.       S_GET_RAW_TYPE (vsp->Symbol) = N_UNDF;
  3799.       return 1;        /* return and indicate no psect */
  3800.     case N_DATA | N_EXT:
  3801.       VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
  3802.                   vsp->Psect_Offset, 1);
  3803.       /* In this case we still generate the psect */
  3804.       break;
  3805.     default:
  3806.       {
  3807.         char Error_Line[256];
  3808.         sprintf (Error_Line,
  3809.              "Globalsymbol attribute for symbol %s was unexpected.\n",
  3810.              Name);
  3811.         error (Error_Line);
  3812.         break;
  3813.       }
  3814.     }            /* switch */
  3815.     }
  3816.  
  3817.   Psect_Attributes &= 0xffff;    /* clear out the globalref/def stuff */
  3818.   /*
  3819.    *    We are writing a GSD record
  3820.    */
  3821.   Set_VMS_Object_File_Record (OBJ_S_C_GSD);
  3822.   /*
  3823.    *    If the buffer is empty we must insert the GSD record type
  3824.    */
  3825.   if (Object_Record_Offset == 0)
  3826.     PUT_CHAR (OBJ_S_C_GSD);
  3827.   /*
  3828.    *    We are writing a PSECT definition subrecord
  3829.    */
  3830.   PUT_CHAR (GSD_S_C_PSC);
  3831.   /*
  3832.    *    Psects are always LONGWORD aligned
  3833.    */
  3834.   PUT_CHAR (2);
  3835.   /*
  3836.    *    Specify the psect attributes
  3837.    */
  3838.   PUT_SHORT (Psect_Attributes);
  3839.   /*
  3840.    *    Specify the allocation
  3841.    */
  3842.   PUT_LONG (Size);
  3843.   /*
  3844.    *    Finally, the psect name
  3845.    */
  3846.   VMS_Case_Hack_Symbol (Name, Local);
  3847.   PUT_COUNTED_STRING (Local);
  3848.   /*
  3849.    *    Flush the buffer if it is more than 75% full
  3850.    */
  3851.   if (Object_Record_Offset >
  3852.       (sizeof (Object_Record_Buffer) * 3 / 4))
  3853.     Flush_VMS_Object_Record_Buffer ();
  3854.   return 0;
  3855. }
  3856.  
  3857.  
  3858. /*
  3859.  *    Given the pointer to a symbol we calculate how big the data at the
  3860.  *    symbol is.  We do this by looking for the next symbol (local or
  3861.  *    global) which will indicate the start of another datum.
  3862.  */
  3863. static int
  3864. VMS_Initialized_Data_Size (sp, End_Of_Data)
  3865.      register struct symbol *sp;
  3866.      int End_Of_Data;
  3867. {
  3868.   struct symbol *sp1, *Next_Symbol;
  3869.   /* Cache values to avoid extra lookups.  */
  3870.   valueT sp_val = S_GET_VALUE (sp), sp1_val, next_val;
  3871.  
  3872.   /*
  3873.    *    Find the next symbol
  3874.    *    it delimits this datum
  3875.    */
  3876.   Next_Symbol = 0;
  3877.   for (sp1 = symbol_rootP; sp1; sp1 = symbol_next (sp1))
  3878.     {
  3879.       /*
  3880.        *    The data type must match
  3881.        */
  3882.       if (S_GET_TYPE (sp1) != N_DATA)
  3883.     continue;
  3884.  
  3885.       sp1_val = S_GET_VALUE (sp1);
  3886.  
  3887.       /*
  3888.        *    The symbol must be AFTER this symbol
  3889.        */
  3890.       if (sp1_val <= sp_val)
  3891.     continue;
  3892.       /*
  3893.        *    We ignore THIS symbol
  3894.        */
  3895.       if (sp1 == sp)
  3896.     continue;
  3897.       /*
  3898.        *    If there is already a candidate selected for the
  3899.        *    next symbol, see if we are a better candidate
  3900.        */
  3901.       if (Next_Symbol)
  3902.     {
  3903.       /*
  3904.        *    We are a better candidate if we are "closer"
  3905.        *    to the symbol
  3906.        */
  3907.       if (sp1_val > next_val)
  3908.         continue;
  3909.     }
  3910.       /*
  3911.        * Make this the candidate
  3912.        */
  3913.       Next_Symbol = sp1;
  3914.       next_val = sp1_val;
  3915.     }
  3916.   /*
  3917.    *    Calculate its size
  3918.    */
  3919.   return Next_Symbol ? (next_val - sp_val) : (End_Of_Data - sp_val);
  3920. }
  3921.  
  3922. /*
  3923.  *    Check symbol names for the Psect hack with a globalvalue, and then
  3924.  *    generate globalvalues for those that have it.
  3925.  */
  3926. static
  3927. VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment)
  3928.      unsigned text_siz;
  3929.      unsigned data_siz;
  3930.      char *Data_Segment;
  3931. {
  3932.   register symbolS *sp;
  3933.   char *stripped_name, *Name;
  3934.   int Size;
  3935.   int Psect_Attributes;
  3936.   int globalvalue;
  3937.  
  3938.   /*
  3939.    * Scan the symbol table for globalvalues, and emit def/ref when
  3940.    * required.  These will be caught again later and converted to
  3941.    * N_UNDF
  3942.    */
  3943.   for (sp = symbol_rootP; sp; sp = sp->sy_next)
  3944.     {
  3945.       /*
  3946.        *    See if this is something we want to look at.
  3947.        */
  3948.       if ((S_GET_RAW_TYPE (sp) != (N_DATA | N_EXT)) &&
  3949.       (S_GET_RAW_TYPE (sp) != (N_UNDF | N_EXT)))
  3950.     continue;
  3951.       /*
  3952.        *    See if this has globalvalue specification.
  3953.        */
  3954.       Name = S_GET_NAME (sp);
  3955.  
  3956.       if (!HAS_PSECT_ATTRIBUTES (Name))
  3957.     continue;
  3958.  
  3959.       stripped_name = (char *) xmalloc (strlen (Name) + 1);
  3960.       strcpy (stripped_name, Name);
  3961.       Psect_Attributes = 0;
  3962.       VMS_Modify_Psect_Attributes (stripped_name, &Psect_Attributes);
  3963.  
  3964.       if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
  3965.     {
  3966.       switch (S_GET_RAW_TYPE (sp))
  3967.         {
  3968.         case N_UNDF | N_EXT:
  3969.           VMS_Global_Symbol_Spec (stripped_name, 0, 0, 2);
  3970.           break;
  3971.         case N_DATA | N_EXT:
  3972.           Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
  3973.           if (Size > 4)
  3974.         error ("Invalid data type for globalvalue");
  3975.           globalvalue = md_chars_to_number (Data_Segment + 
  3976.              S_GET_VALUE (sp) - text_siz , Size);
  3977.           /* Three times for good luck.  The linker seems to get confused
  3978.              if there are fewer than three */
  3979.           VMS_Global_Symbol_Spec (stripped_name, 0, 0, 2);
  3980.           VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue, 3);
  3981.           VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue, 3);
  3982.           break;
  3983.         default:
  3984.           printf (" Invalid globalvalue of %s\n", stripped_name);
  3985.           break;
  3986.         }            /* switch */
  3987.     }            /* if */
  3988.       free (stripped_name);    /* clean up */
  3989.     }                /* for */
  3990.  
  3991. }
  3992.  
  3993.  
  3994. /*
  3995.  *    Define a procedure entry pt/mask
  3996.  */
  3997. static
  3998. VMS_Procedure_Entry_Pt (Name, Psect_Number, Psect_Offset, Entry_Mask)
  3999.      char *Name;
  4000.      int Psect_Number;
  4001.      int Psect_Offset;
  4002.      int Entry_Mask;
  4003. {
  4004.   char Local[32];
  4005.  
  4006.   /*
  4007.    *    We are writing a GSD record
  4008.    */
  4009.   Set_VMS_Object_File_Record (OBJ_S_C_GSD);
  4010.   /*
  4011.    *    If the buffer is empty we must insert the GSD record type
  4012.    */
  4013.   if (Object_Record_Offset == 0)
  4014.     PUT_CHAR (OBJ_S_C_GSD);
  4015.   /*
  4016.    *    We are writing a Procedure Entry Pt/Mask subrecord
  4017.    */
  4018.   if (Psect_Number <= 255)
  4019.     {
  4020.       PUT_CHAR (GSD_S_C_EPM);
  4021.     }
  4022.   else
  4023.     {
  4024.       PUT_CHAR (GSD_S_C_EPMW);
  4025.     }
  4026.   /*
  4027.    *    Data type is undefined
  4028.    */
  4029.   PUT_CHAR (0);
  4030.   /*
  4031.    *    Flags = "RELOCATABLE" and "DEFINED"
  4032.    */
  4033.   PUT_SHORT (GSY_S_M_DEF | GSY_S_M_REL);
  4034.   /*
  4035.    *    Psect Number
  4036.    */
  4037.   if (Psect_Number <= 255)
  4038.     {
  4039.       PUT_CHAR (Psect_Number);
  4040.     }
  4041.   else
  4042.     {
  4043.       PUT_SHORT (Psect_Number);
  4044.     }
  4045.   /*
  4046.    *    Offset
  4047.    */
  4048.   PUT_LONG (Psect_Offset);
  4049.   /*
  4050.    *    Entry mask
  4051.    */
  4052.   PUT_SHORT (Entry_Mask);
  4053.   /*
  4054.    *    Finally, the global symbol name
  4055.    */
  4056.   VMS_Case_Hack_Symbol (Name, Local);
  4057.   PUT_COUNTED_STRING (Local);
  4058.   /*
  4059.    *    Flush the buffer if it is more than 75% full
  4060.    */
  4061.   if (Object_Record_Offset >
  4062.       (sizeof (Object_Record_Buffer) * 3 / 4))
  4063.     Flush_VMS_Object_Record_Buffer ();
  4064. }
  4065.  
  4066.  
  4067. /*
  4068.  *    Set the current location counter to a particular Psect and Offset
  4069.  */
  4070. static
  4071. VMS_Set_Psect (Psect_Index, Offset, Record_Type)
  4072.      int Psect_Index;
  4073.      int Offset;
  4074.      int Record_Type;
  4075. {
  4076.   /*
  4077.    *    We are writing a "Record_Type" record
  4078.    */
  4079.   Set_VMS_Object_File_Record (Record_Type);
  4080.   /*
  4081.    *    If the buffer is empty we must insert the record type
  4082.    */
  4083.   if (Object_Record_Offset == 0)
  4084.     PUT_CHAR (Record_Type);
  4085.   /*
  4086.    *    Stack the Psect base + Longword Offset
  4087.    */
  4088.   if (Psect_Index < 255)
  4089.     {
  4090.       PUT_CHAR (TIR_S_C_STA_PL);
  4091.       PUT_CHAR (Psect_Index);
  4092.     }
  4093.   else
  4094.     {
  4095.       PUT_CHAR (TIR_S_C_STA_WPL);
  4096.       PUT_SHORT (Psect_Index);
  4097.     }
  4098.   PUT_LONG (Offset);
  4099.   /*
  4100.    *    Set relocation base
  4101.    */
  4102.   PUT_CHAR (TIR_S_C_CTL_SETRB);
  4103.   /*
  4104.    *    Flush the buffer if it is more than 75% full
  4105.    */
  4106.   if (Object_Record_Offset >
  4107.       (sizeof (Object_Record_Buffer) * 3 / 4))
  4108.     Flush_VMS_Object_Record_Buffer ();
  4109. }
  4110.  
  4111.  
  4112. /*
  4113.  *    Store repeated immediate data in current Psect
  4114.  */
  4115. static
  4116. VMS_Store_Repeated_Data (Repeat_Count, Pointer, Size, Record_Type)
  4117.      int Repeat_Count;
  4118.      register char *Pointer;
  4119.      int Size;
  4120.      int Record_Type;
  4121. {
  4122.  
  4123.   /*
  4124.    *    Ignore zero bytes/words/longwords
  4125.    */
  4126.   if ((Size == sizeof (char)) && (*Pointer == 0))
  4127.     return;
  4128.   if ((Size == sizeof (short)) && (*(short *) Pointer == 0))
  4129.     return;
  4130.   if ((Size == sizeof (long)) && (*(long *) Pointer == 0))
  4131.     return;
  4132.   /*
  4133.    *    If the data is too big for a TIR_S_C_STO_RIVB sub-record
  4134.    *    then we do it manually
  4135.    */
  4136.   if (Size > 255)
  4137.     {
  4138.       while (--Repeat_Count >= 0)
  4139.     VMS_Store_Immediate_Data (Pointer, Size, Record_Type);
  4140.       return;
  4141.     }
  4142.   /*
  4143.    *    We are writing a "Record_Type" record
  4144.    */
  4145.   Set_VMS_Object_File_Record (Record_Type);
  4146.   /*
  4147.    *    If the buffer is empty we must insert record type
  4148.    */
  4149.   if (Object_Record_Offset == 0)
  4150.     PUT_CHAR (Record_Type);
  4151.   /*
  4152.    *    Stack the repeat count
  4153.    */
  4154.   PUT_CHAR (TIR_S_C_STA_LW);
  4155.   PUT_LONG (Repeat_Count);
  4156.   /*
  4157.    *    And now the command and its data
  4158.    */
  4159.   PUT_CHAR (TIR_S_C_STO_RIVB);
  4160.   PUT_CHAR (Size);
  4161.   while (--Size >= 0)
  4162.     PUT_CHAR (*Pointer++);
  4163.   /*
  4164.    *    Flush the buffer if it is more than 75% full
  4165.    */
  4166.   if (Object_Record_Offset >
  4167.       (sizeof (Object_Record_Buffer) * 3 / 4))
  4168.     Flush_VMS_Object_Record_Buffer ();
  4169. }
  4170.  
  4171.  
  4172. /*
  4173.  *    Store a Position Independent Reference
  4174.  */
  4175. static
  4176. VMS_Store_PIC_Symbol_Reference (Symbol, Offset, PC_Relative,
  4177.                 Psect, Psect_Offset, Record_Type)
  4178.      struct symbol *Symbol;
  4179.      int Offset;
  4180.      int PC_Relative;
  4181.      int Psect;
  4182.      int Psect_Offset;
  4183.      int Record_Type;
  4184. {
  4185.   register struct VMS_Symbol *vsp =
  4186.   (struct VMS_Symbol *) (Symbol->sy_number);
  4187.   char Local[32];
  4188.  
  4189.   /*
  4190.    *    We are writing a "Record_Type" record
  4191.    */
  4192.   Set_VMS_Object_File_Record (Record_Type);
  4193.   /*
  4194.    *    If the buffer is empty we must insert record type
  4195.    */
  4196.   if (Object_Record_Offset == 0)
  4197.     PUT_CHAR (Record_Type);
  4198.   /*
  4199.    *    Set to the appropriate offset in the Psect
  4200.    */
  4201.   if (PC_Relative)
  4202.     {
  4203.       /*
  4204.        *    For a Code reference we need to fix the operand
  4205.        *    specifier as well (so back up 1 byte)
  4206.        */
  4207.       VMS_Set_Psect (Psect, Psect_Offset - 1, Record_Type);
  4208.     }
  4209.   else
  4210.     {
  4211.       /*
  4212.        *    For a Data reference we just store HERE
  4213.        */
  4214.       VMS_Set_Psect (Psect, Psect_Offset, Record_Type);
  4215.     }
  4216.   /*
  4217.    *    Make sure we are still generating a "Record Type" record
  4218.    */
  4219.   if (Object_Record_Offset == 0)
  4220.     PUT_CHAR (Record_Type);
  4221.   /*
  4222.    *    Dispatch on symbol type (so we can stack its value)
  4223.    */
  4224.   switch (S_GET_RAW_TYPE (Symbol))
  4225.     {
  4226.       /*
  4227.        *    Global symbol
  4228.        */
  4229. #ifdef    NOT_VAX_11_C_COMPATIBLE
  4230.     case N_UNDF | N_EXT:
  4231.     case N_DATA | N_EXT:
  4232. #endif    /* NOT_VAX_11_C_COMPATIBLE */
  4233.     case N_UNDF:
  4234.     case N_TEXT | N_EXT:
  4235.       /*
  4236.        *    Get the symbol name (case hacked)
  4237.        */
  4238.       VMS_Case_Hack_Symbol (S_GET_NAME (Symbol), Local);
  4239.       /*
  4240.        *    Stack the global symbol value
  4241.        */
  4242.       PUT_CHAR (TIR_S_C_STA_GBL);
  4243.       PUT_COUNTED_STRING (Local);
  4244.       if (Offset)
  4245.     {
  4246.       /*
  4247.        *    Stack the longword offset
  4248.        */
  4249.       PUT_CHAR (TIR_S_C_STA_LW);
  4250.       PUT_LONG (Offset);
  4251.       /*
  4252.        *    Add the two, leaving the result on the stack
  4253.        */
  4254.       PUT_CHAR (TIR_S_C_OPR_ADD);
  4255.     }
  4256.       break;
  4257.       /*
  4258.        *    Uninitialized local data
  4259.        */
  4260.     case N_BSS:
  4261.       /*
  4262.        *    Stack the Psect (+offset)
  4263.        */
  4264.       if (vsp->Psect_Index < 255)
  4265.     {
  4266.       PUT_CHAR (TIR_S_C_STA_PL);
  4267.       PUT_CHAR (vsp->Psect_Index);
  4268.     }
  4269.       else
  4270.     {
  4271.       PUT_CHAR (TIR_S_C_STA_WPL);
  4272.       PUT_SHORT (vsp->Psect_Index);
  4273.     }
  4274.       PUT_LONG (vsp->Psect_Offset + Offset);
  4275.       break;
  4276.       /*
  4277.        *    Local text
  4278.        */
  4279.     case N_TEXT:
  4280.       /*
  4281.        *    Stack the Psect (+offset)
  4282.        */
  4283.       if (vsp->Psect_Index < 255)
  4284.     {
  4285.       PUT_CHAR (TIR_S_C_STA_PL);
  4286.       PUT_CHAR (vsp->Psect_Index);
  4287.     }
  4288.       else
  4289.     {
  4290.       PUT_CHAR (TIR_S_C_STA_WPL);
  4291.       PUT_SHORT (vsp->Psect_Index);
  4292.     }
  4293.       PUT_LONG (S_GET_VALUE (Symbol) + Offset);
  4294.       break;
  4295.       /*
  4296.        *    Initialized local or global data
  4297.        */
  4298.     case N_DATA:
  4299. #ifndef    NOT_VAX_11_C_COMPATIBLE
  4300.     case N_UNDF | N_EXT:
  4301.     case N_DATA | N_EXT:
  4302. #endif    /* NOT_VAX_11_C_COMPATIBLE */
  4303.       /*
  4304.        *    Stack the Psect (+offset)
  4305.        */
  4306.       if (vsp->Psect_Index < 255)
  4307.     {
  4308.       PUT_CHAR (TIR_S_C_STA_PL);
  4309.       PUT_CHAR (vsp->Psect_Index);
  4310.     }
  4311.       else
  4312.     {
  4313.       PUT_CHAR (TIR_S_C_STA_WPL);
  4314.       PUT_SHORT (vsp->Psect_Index);
  4315.     }
  4316.       PUT_LONG (vsp->Psect_Offset + Offset);
  4317.       break;
  4318.     }
  4319.   /*
  4320.    *    Store either a code or data reference
  4321.    */
  4322.   PUT_CHAR (PC_Relative ? TIR_S_C_STO_PICR : TIR_S_C_STO_PIDR);
  4323.   /*
  4324.    *    Flush the buffer if it is more than 75% full
  4325.    */
  4326.   if (Object_Record_Offset >
  4327.       (sizeof (Object_Record_Buffer) * 3 / 4))
  4328.     Flush_VMS_Object_Record_Buffer ();
  4329. }
  4330.  
  4331.  
  4332. /*
  4333.  *    Check in the text area for an indirect pc-relative reference
  4334.  *    and fix it up with addressing mode 0xff [PC indirect]
  4335.  *
  4336.  *    THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
  4337.  *    PIC CODE GENERATING FIXUP ROUTINE.
  4338.  */
  4339. static
  4340. VMS_Fix_Indirect_Reference (Text_Psect, Offset, fragP, text_frag_root)
  4341.      int Text_Psect;
  4342.      int Offset;
  4343.      register fragS *fragP;
  4344.      struct frag *text_frag_root;
  4345. {
  4346.   /*
  4347.    *    The addressing mode byte is 1 byte before the address
  4348.    */
  4349.   Offset--;
  4350.   /*
  4351.    *    Is it in THIS frag??
  4352.    */
  4353.   if ((Offset < fragP->fr_address) ||
  4354.       (Offset >= (fragP->fr_address + fragP->fr_fix)))
  4355.     {
  4356.       /*
  4357.        *    We need to search for the fragment containing this
  4358.        *    Offset
  4359.        */
  4360.       for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
  4361.     {
  4362.       if ((Offset >= fragP->fr_address) &&
  4363.           (Offset < (fragP->fr_address + fragP->fr_fix)))
  4364.         break;
  4365.     }
  4366.       /*
  4367.        *    If we couldn't find the frag, things are BAD!!
  4368.        */
  4369.       if (fragP == 0)
  4370.     error ("Couldn't find fixup fragment when checking for indirect reference");
  4371.     }
  4372.   /*
  4373.    *    Check for indirect PC relative addressing mode
  4374.    */
  4375.   if (fragP->fr_literal[Offset - fragP->fr_address] == (char) 0xff)
  4376.     {
  4377.       static char Address_Mode = 0xff;
  4378.  
  4379.       /*
  4380.        *    Yes: Store the indirect mode back into the image
  4381.        *         to fix up the damage done by STO_PICR
  4382.        */
  4383.       VMS_Set_Psect (Text_Psect, Offset, OBJ_S_C_TIR);
  4384.       VMS_Store_Immediate_Data (&Address_Mode, 1, OBJ_S_C_TIR);
  4385.     }
  4386. }
  4387.  
  4388. /*
  4389.  *    If the procedure "main()" exists we have to add the instruction
  4390.  *    "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
  4391.  */
  4392. VMS_Check_For_Main ()
  4393. {
  4394.   register symbolS *symbolP;
  4395. #ifdef    HACK_DEC_C_STARTUP    /* JF */
  4396.   register struct frchain *frchainP;
  4397.   register fragS *fragP;
  4398.   register fragS **prev_fragPP;
  4399.   register struct fix *fixP;
  4400.   register fragS *New_Frag;
  4401.   int i;
  4402. #endif    /* HACK_DEC_C_STARTUP */
  4403.  
  4404.   symbolP = (struct symbol *) symbol_find ("_main");
  4405.   if (symbolP && !S_IS_DEBUG (symbolP) &&
  4406.       S_IS_EXTERNAL (symbolP) && (S_GET_TYPE (symbolP) == N_TEXT))
  4407.     {
  4408. #ifdef    HACK_DEC_C_STARTUP
  4409.       if (!flag_hash_long_names)
  4410.     {
  4411. #endif
  4412.       /*
  4413.        *    Remember the entry point symbol
  4414.        */
  4415.       Entry_Point_Symbol = symbolP;
  4416. #ifdef HACK_DEC_C_STARTUP
  4417.     }
  4418.       else
  4419.     {
  4420.       /*
  4421.        *    Scan all the fragment chains for the one with "_main"
  4422.        *    (Actually we know the fragment from the symbol, but we need
  4423.        *     the previous fragment so we can change its pointer)
  4424.        */
  4425.       frchainP = frchain_root;
  4426.       while (frchainP)
  4427.         {
  4428.           /*
  4429.            *    Scan all the fragments in this chain, remembering
  4430.            *    the "previous fragment"
  4431.            */
  4432.           prev_fragPP = &frchainP->frch_root;
  4433.           fragP = frchainP->frch_root;
  4434.           while (fragP && (fragP != frchainP->frch_last))
  4435.         {
  4436.           /*
  4437.            *    Is this the fragment?
  4438.            */
  4439.           if (fragP == symbolP->sy_frag)
  4440.             {
  4441.               /*
  4442.                *    Yes: Modify the fragment by replacing
  4443.                *         it with a new fragment.
  4444.                */
  4445.               New_Frag = (fragS *)
  4446.             xmalloc (sizeof (*New_Frag) +
  4447.                  fragP->fr_fix +
  4448.                  fragP->fr_var +
  4449.                  5);
  4450.               /*
  4451.                *    The fragments are the same except
  4452.                *    that the "fixed" area is larger
  4453.                */
  4454.               *New_Frag = *fragP;
  4455.               New_Frag->fr_fix += 6;
  4456.               /*
  4457.                *    Copy the literal data opening a hole
  4458.                *    2 bytes after "_main" (i.e. just after
  4459.                *    the entry mask).  Into which we place
  4460.                *    the JSB instruction.
  4461.                */
  4462.               New_Frag->fr_literal[0] = fragP->fr_literal[0];
  4463.               New_Frag->fr_literal[1] = fragP->fr_literal[1];
  4464.               New_Frag->fr_literal[2] = 0x16;    /* Jsb */
  4465.               New_Frag->fr_literal[3] = 0xef;
  4466.               New_Frag->fr_literal[4] = 0;
  4467.               New_Frag->fr_literal[5] = 0;
  4468.               New_Frag->fr_literal[6] = 0;
  4469.               New_Frag->fr_literal[7] = 0;
  4470.               for (i = 2; i < fragP->fr_fix + fragP->fr_var; i++)
  4471.             New_Frag->fr_literal[i + 6] =
  4472.               fragP->fr_literal[i];
  4473.               /*
  4474.                *    Now replace the old fragment with the
  4475.                *    newly generated one.
  4476.                */
  4477.               *prev_fragPP = New_Frag;
  4478.               /*
  4479.                *    Remember the entry point symbol
  4480.                */
  4481.               Entry_Point_Symbol = symbolP;
  4482.               /*
  4483.                *    Scan the text area fixup structures
  4484.                *    as offsets in the fragment may have
  4485.                *    changed
  4486.                */
  4487.               for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
  4488.             {
  4489.               /*
  4490.                *    Look for references to this
  4491.                *    fragment.
  4492.                */
  4493.               if (fixP->fx_frag == fragP)
  4494.                 {
  4495.                   /*
  4496.                    *    Change the fragment
  4497.                    *    pointer
  4498.                    */
  4499.                   fixP->fx_frag = New_Frag;
  4500.                   /*
  4501.                    *    If the offset is after
  4502.                    *    the entry mask we need
  4503.                    *    to account for the JSB
  4504.                    *    instruction we just
  4505.                    *    inserted.
  4506.                    */
  4507.                   if (fixP->fx_where >= 2)
  4508.                 fixP->fx_where += 6;
  4509.                 }
  4510.             }
  4511.               /*
  4512.                *    Scan the symbols as offsets in the
  4513.                *    fragment may have changed
  4514.                */
  4515.               for (symbolP = symbol_rootP;
  4516.                symbolP;
  4517.                symbolP = symbol_next (symbolP))
  4518.             {
  4519.               /*
  4520.                *    Look for references to this
  4521.                *    fragment.
  4522.                */
  4523.               if (symbolP->sy_frag == fragP)
  4524.                 {
  4525.                   /*
  4526.                    *    Change the fragment
  4527.                    *    pointer
  4528.                    */
  4529.                   symbolP->sy_frag = New_Frag;
  4530.                   /*
  4531.                    *    If the offset is after
  4532.                    *    the entry mask we need
  4533.                    *    to account for the JSB
  4534.                    *    instruction we just
  4535.                    *    inserted.
  4536.                    */
  4537.                   if (S_GET_VALUE (symbolP) >= 2)
  4538.                 S_SET_VALUE (symbolP,
  4539.                          S_GET_VALUE (symbolP) + 6);
  4540.                 }
  4541.             }
  4542.               /*
  4543.                *    Make a symbol reference to
  4544.                *    "_c$main_args" so we can get
  4545.                *    its address inserted into the
  4546.                *    JSB instruction.
  4547.                */
  4548.               symbolP = (symbolS *) xmalloc (sizeof (*symbolP));
  4549.               S_SET_NAME (symbolP, "_C$MAIN_ARGS");
  4550.               S_SET_TYPE (symbolP, N_UNDF);
  4551.               S_SET_OTHER (symbolP, 0);
  4552.               S_SET_DESC (symbolP, 0);
  4553.               S_SET_VALUE (symbolP, 0);
  4554.               symbolP->sy_name_offset = 0;
  4555.               symbolP->sy_number = 0;
  4556.               symbolP->sy_frag = New_Frag;
  4557.               symbolP->sy_resolved = 0;
  4558.               symbolP->sy_resolving = 0;
  4559.               /* this actually inserts at the beginning of the list */
  4560.               symbol_append (symbol_rootP, symbolP, &symbol_rootP, &symbol_lastP);
  4561.  
  4562.               symbol_rootP = symbolP;
  4563.               /*
  4564.                *    Generate a text fixup structure
  4565.                *    to get "_c$main_args" stored into the
  4566.                *    JSB instruction.
  4567.                */
  4568.               fixP = (struct fix *) xmalloc (sizeof (*fixP));
  4569.               fixP->fx_frag = New_Frag;
  4570.               fixP->fx_where = 4;
  4571.               fixP->fx_addsy = symbolP;
  4572.               fixP->fx_subsy = 0;
  4573.               fixP->fx_offset = 0;
  4574.               fixP->fx_size = sizeof (long);
  4575.               fixP->fx_pcrel = 1;
  4576.               fixP->fx_next = text_fix_root;
  4577.               text_fix_root = fixP;
  4578.               /*
  4579.                *    Now make sure we exit from the loop
  4580.                */
  4581.               frchainP = 0;
  4582.               break;
  4583.             }
  4584.           /*
  4585.            *    Try the next fragment
  4586.            */
  4587.           prev_fragPP = &fragP->fr_next;
  4588.           fragP = fragP->fr_next;
  4589.         }
  4590.           /*
  4591.            *    Try the next fragment chain
  4592.            */
  4593.           if (frchainP)
  4594.         frchainP = frchainP->frch_next;
  4595.         }
  4596.     }
  4597. #endif /* HACK_DEC_C_STARTUP */
  4598.     }
  4599. }
  4600.  
  4601. /*
  4602.  *    Write a VAX/VMS object file (everything else has been done!)
  4603.  */
  4604. VMS_write_object_file (text_siz, data_siz, bss_siz, text_frag_root,
  4605.                data_frag_root)
  4606.      unsigned text_siz;
  4607.      unsigned data_siz;
  4608.      unsigned bss_siz;
  4609.      struct frag *text_frag_root;
  4610.      struct frag *data_frag_root;
  4611. {
  4612.   register fragS *fragP;
  4613.   register symbolS *symbolP;
  4614.   register symbolS *sp;
  4615.   register struct fix *fixP;
  4616.   register struct VMS_Symbol *vsp;
  4617.   char *Data_Segment;
  4618.   int Local_Initialized_Data_Size = 0;
  4619.   int Globalref;
  4620.   int Psect_Number = 0;        /* Psect Index Number */
  4621.   int Text_Psect = -1;        /* Text Psect Index   */
  4622.   int Data_Psect = -2;        /* Data Psect Index   JF: Was -1 */
  4623.   int Bss_Psect = -3;        /* Bss Psect Index    JF: Was -1 */
  4624.  
  4625.   /*
  4626.    *    Create the VMS object file
  4627.    */
  4628.   Create_VMS_Object_File ();
  4629.   /*
  4630.    *    Write the module header records
  4631.    */
  4632.   Write_VMS_MHD_Records ();
  4633.  
  4634.   /*
  4635.    *    Store the Data segment:
  4636.    *
  4637.    *    Since this is REALLY hard to do any other way,
  4638.    *    we actually manufacture the data segment and
  4639.    *    the store the appropriate values out of it.
  4640.    *    We need to generate this early, so that globalvalues
  4641.    *    can be properly emitted.
  4642.    */
  4643.   if (data_siz > 0)
  4644.     {
  4645.       /*
  4646.        *    Allocate the data segment
  4647.        */
  4648.       Data_Segment = (char *) xmalloc (data_siz);
  4649.       /*
  4650.        *    Run through the data fragments, filling in the segment
  4651.        */
  4652.       for (fragP = data_frag_root; fragP; fragP = fragP->fr_next)
  4653.     {
  4654.       register long int count;
  4655.       register char *fill_literal;
  4656.       register long int fill_size;
  4657.       int i;
  4658.  
  4659.       i = fragP->fr_address - text_siz;
  4660.       if (fragP->fr_fix)
  4661.         memcpy (Data_Segment + i,
  4662.             fragP->fr_literal,
  4663.             fragP->fr_fix);
  4664.       i += fragP->fr_fix;
  4665.  
  4666.       fill_literal = fragP->fr_literal + fragP->fr_fix;
  4667.       fill_size = fragP->fr_var;
  4668.       for (count = fragP->fr_offset; count; count--)
  4669.         {
  4670.           if (fill_size)
  4671.         memcpy (Data_Segment + i, fill_literal, fill_size);
  4672.           i += fill_size;
  4673.         }
  4674.     }
  4675.     }
  4676.  
  4677.  
  4678.   /*
  4679.    *    Generate the VMS object file records
  4680.    *    1st GSD then TIR records
  4681.    */
  4682.  
  4683.   /*******       Global Symbol Dictionary       *******/
  4684.   /*
  4685.    * Emit globalvalues now.  We must do this before the text psect
  4686.    * is defined, or we will get linker warnings about multiply defined
  4687.    * symbols.  All of the globalvalues "reference" psect 0, although
  4688.    * it really does not have anything to do with it.
  4689.    */
  4690.   VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment);
  4691.   /*
  4692.    *    Define the Text Psect
  4693.    */
  4694.   Text_Psect = Psect_Number++;
  4695.   VMS_Psect_Spec ("$code", text_siz, "TEXT", 0);
  4696.   /*
  4697.    *    Define the BSS Psect
  4698.    */
  4699.   if (bss_siz > 0)
  4700.     {
  4701.       Bss_Psect = Psect_Number++;
  4702.       VMS_Psect_Spec ("$uninitialized_data", bss_siz, "DATA", 0);
  4703.     }
  4704. #ifndef gxx_bug_fixed
  4705.   /* 
  4706.    * The g++ compiler does not write out external references to vtables
  4707.    * correctly.  Check for this and holler if we see it happening.
  4708.    * If that compiler bug is ever fixed we can remove this.
  4709.    */
  4710.   for (sp = symbol_rootP; sp; sp = symbol_next (sp)) 
  4711.     {
  4712.       /*
  4713.        *    Dispatch on symbol type
  4714.        */
  4715.       switch (S_GET_RAW_TYPE (sp)) {
  4716.     /*
  4717.      *    Global Reference
  4718.      */
  4719.       case N_UNDF:
  4720.     /*
  4721.      *    Make a GSD global symbol reference
  4722.      *    record.
  4723.      */
  4724.     if (strncmp (S_GET_NAME (sp),"__vt.",5) == 0)
  4725.       {
  4726.         S_GET_RAW_TYPE (sp) = N_UNDF | N_EXT;
  4727.         S_SET_OTHER (sp, 1);
  4728.         /* Is this warning still needed?  It sounds like it describes
  4729.            a compiler bug.  Does it?  If not, let's dump it.  */
  4730.         as_warn("g++ wrote an extern reference to %s as a routine.",
  4731.             S_GET_NAME (sp));
  4732.         as_warn("I will fix it, but I hope that it was not really a routine");
  4733.       }
  4734.     break;
  4735.       default:
  4736.     break;
  4737.       }
  4738.     }
  4739. #endif /* gxx_bug_fixed */
  4740.   /*
  4741.    *    Now scan the symbols and emit the appropriate GSD records
  4742.    */
  4743.   for (sp = symbol_rootP; sp; sp = symbol_next (sp))
  4744.     {
  4745.       /*
  4746.        *    Dispatch on symbol type
  4747.        */
  4748.       switch (S_GET_RAW_TYPE (sp))
  4749.     {
  4750.       /*
  4751.        *    Global uninitialized data
  4752.        */
  4753.     case N_UNDF | N_EXT:
  4754.       /*
  4755.        *    Make a VMS data symbol entry
  4756.        */
  4757.       vsp = (struct VMS_Symbol *)
  4758.         xmalloc (sizeof (*vsp));
  4759.       vsp->Symbol = sp;
  4760.       vsp->Size = S_GET_VALUE (sp);
  4761.       vsp->Psect_Index = Psect_Number++;
  4762.       vsp->Psect_Offset = 0;
  4763.       vsp->Next = VMS_Symbols;
  4764.       VMS_Symbols = vsp;
  4765.       sp->sy_number = (int) vsp;
  4766.       /*
  4767.        *    Make the psect for this data
  4768.        */
  4769.       Globalref = VMS_Psect_Spec (
  4770.                        S_GET_NAME (sp),
  4771.                        vsp->Size,
  4772.                        S_GET_OTHER (sp) ? "CONST" : "COMMON",
  4773.                        vsp);
  4774.       if (Globalref)
  4775.         Psect_Number--;
  4776.  
  4777. /* See if this is an external vtable.  We want to help the linker find
  4778.    these things in libraries, so we make a symbol reference.  This
  4779.    is not compatible with VAX-C usage for variables, but since vtables are
  4780.    only used internally by g++, we can get away with this hack.  */
  4781.  
  4782.       if(strncmp (S_GET_NAME (sp), "__vt.", 5) == 0)
  4783.         VMS_Global_Symbol_Spec (S_GET_NAME(sp),
  4784.                     vsp->Psect_Index,
  4785.                     0,
  4786.                     0);
  4787.  
  4788. #ifdef    NOT_VAX_11_C_COMPATIBLE
  4789.       /*
  4790.        *    Place a global symbol at the
  4791.        *    beginning of the Psect
  4792.        */
  4793.       VMS_Global_Symbol_Spec (S_GET_NAME (sp),
  4794.                   vsp->Psect_Index,
  4795.                   0,
  4796.                   1);
  4797. #endif    /* NOT_VAX_11_C_COMPATIBLE */
  4798.       break;
  4799.       /*
  4800.        *    Local uninitialized data
  4801.        */
  4802.     case N_BSS:
  4803.       /*
  4804.        *    Make a VMS data symbol entry
  4805.        */
  4806.       vsp = (struct VMS_Symbol *)
  4807.         xmalloc (sizeof (*vsp));
  4808.       vsp->Symbol = sp;
  4809.       vsp->Size = 0;
  4810.       vsp->Psect_Index = Bss_Psect;
  4811.       vsp->Psect_Offset =
  4812.         S_GET_VALUE (sp) -
  4813.         bss_address_frag.fr_address;
  4814.       vsp->Next = VMS_Symbols;
  4815.       VMS_Symbols = vsp;
  4816.       sp->sy_number = (int) vsp;
  4817.       break;
  4818.       /*
  4819.        *    Global initialized data
  4820.        */
  4821.     case N_DATA | N_EXT:
  4822.       /*
  4823.        *    Make a VMS data symbol entry
  4824.        */
  4825.       vsp = (struct VMS_Symbol *)
  4826.         xmalloc (sizeof (*vsp));
  4827.       vsp->Symbol = sp;
  4828.       vsp->Size = VMS_Initialized_Data_Size (sp,
  4829.                          text_siz + data_siz);
  4830.       vsp->Psect_Index = Psect_Number++;
  4831.       vsp->Psect_Offset = 0;
  4832.       vsp->Next = VMS_Symbols;
  4833.       VMS_Symbols = vsp;
  4834.       sp->sy_number = (int) vsp;
  4835.       /*
  4836.        *    Make its psect
  4837.        */
  4838.       Globalref = VMS_Psect_Spec (
  4839.                        S_GET_NAME (sp),
  4840.                        vsp->Size,
  4841.                        S_GET_OTHER (sp) ? "CONST" : "COMMON",
  4842.                        vsp);
  4843.       if (Globalref)
  4844.         Psect_Number--;
  4845.  
  4846. /* See if this is an external vtable.  We want to help the linker find
  4847.    these things in libraries, so we make a symbol definition.  This
  4848.    is not compatible with VAX-C usage for variables, but since vtables are
  4849.    only used internally by g++, we can get away with this hack.  */
  4850.  
  4851.       if(strncmp (S_GET_NAME (sp), "__vt.", 5) == 0)
  4852.         VMS_Global_Symbol_Spec (S_GET_NAME (sp),
  4853.                     vsp->Psect_Index,
  4854.                     0,
  4855.                     1);
  4856.  
  4857. #ifdef    NOT_VAX_11_C_COMPATIBLE
  4858.       /*
  4859.        *    Place a global symbol at the
  4860.        *    beginning of the Psect
  4861.        */
  4862.       VMS_Global_Symbol_Spec (S_GET_NAME (sp),
  4863.                   vsp->Psect_Index,
  4864.                   0,
  4865.                   1);
  4866. #endif    /* NOT_VAX_11_C_COMPATIBLE */
  4867.       break;
  4868.       /*
  4869.        *    Local initialized data
  4870.        */
  4871.     case N_DATA:
  4872.       /*
  4873.        *    Make a VMS data symbol entry
  4874.        */
  4875.       vsp = (struct VMS_Symbol *)
  4876.         xmalloc (sizeof (*vsp));
  4877.       vsp->Symbol = sp;
  4878.       vsp->Size =
  4879.         VMS_Initialized_Data_Size (sp,
  4880.                        text_siz + data_siz);
  4881.       vsp->Psect_Index = Data_Psect;
  4882.       vsp->Psect_Offset =
  4883.         Local_Initialized_Data_Size;
  4884.       Local_Initialized_Data_Size += vsp->Size;
  4885.       vsp->Next = VMS_Symbols;
  4886.       VMS_Symbols = vsp;
  4887.       sp->sy_number = (int) vsp;
  4888.       break;
  4889.       /*
  4890.        *    Global Text definition
  4891.        */
  4892.     case N_TEXT | N_EXT:
  4893.       {
  4894.         unsigned short Entry_Mask;
  4895.  
  4896.         /*
  4897.          *    Get the entry mask
  4898.          */
  4899.         fragP = sp->sy_frag;
  4900.  
  4901.         /* If first frag doesn't contain the data, what do we do?
  4902.            If it's possibly smaller than two bytes, that would
  4903.            imply that the entry mask is not stored where we're
  4904.            expecting it.
  4905.  
  4906.            If you can find a test case that triggers this, report
  4907.            it (and tell me what the entry mask field ought to be),
  4908.            and I'll try to fix it.  KR */
  4909.         /* First frag might be empty if we're generating listings.
  4910.            So skip empty rs_fill frags.  */
  4911.         while (fragP && fragP->fr_type == rs_fill && fragP->fr_fix == 0)
  4912.           fragP = fragP->fr_next;
  4913.  
  4914.         if (fragP->fr_fix < 2)
  4915.           abort ();
  4916.  
  4917.         Entry_Mask = (fragP->fr_literal[0] & 0xff) +
  4918.           ((fragP->fr_literal[1] & 0xff)
  4919.            << 8);
  4920.         /*
  4921.          *    Define the Procedure entry pt.
  4922.          */
  4923.         VMS_Procedure_Entry_Pt (S_GET_NAME (sp),
  4924.                     Text_Psect,
  4925.                     S_GET_VALUE (sp),
  4926.                     Entry_Mask);
  4927.         break;
  4928.       }
  4929.       /*
  4930.        *    Local Text definition
  4931.        */
  4932.     case N_TEXT:
  4933.       /*
  4934.        *    Make a VMS data symbol entry
  4935.        */
  4936.       if (Text_Psect != -1)
  4937.         {
  4938.           vsp = (struct VMS_Symbol *)
  4939.         xmalloc (sizeof (*vsp));
  4940.           vsp->Symbol = sp;
  4941.           vsp->Size = 0;
  4942.           vsp->Psect_Index = Text_Psect;
  4943.           vsp->Psect_Offset = S_GET_VALUE (sp);
  4944.           vsp->Next = VMS_Symbols;
  4945.           VMS_Symbols = vsp;
  4946.           sp->sy_number = (int) vsp;
  4947.         }
  4948.       break;
  4949.       /*
  4950.        *    Global Reference
  4951.        */
  4952.     case N_UNDF:
  4953.       /*
  4954.        *    Make a GSD global symbol reference
  4955.        *    record.
  4956.        */
  4957.       VMS_Global_Symbol_Spec (S_GET_NAME (sp),
  4958.                   0,
  4959.                   0,
  4960.                   0);
  4961.       break;
  4962.       /*
  4963.        *    Anything else
  4964.        */
  4965.     default:
  4966.       /*
  4967.        *    Ignore STAB symbols
  4968.        *    Including .stabs emitted by g++
  4969.        */
  4970.       if (S_IS_DEBUG (sp) || (S_GET_TYPE (sp) == 22))
  4971.         break;
  4972.       /*
  4973.        *    Error
  4974.        */
  4975.       if (S_GET_TYPE (sp) != 22)
  4976.         printf (" ERROR, unknown type (%d)\n",
  4977.             S_GET_TYPE (sp));
  4978.       break;
  4979.     }
  4980.     }
  4981.   /*
  4982.    *    Define the Data Psect
  4983.    */
  4984.   if ((data_siz > 0) && (Local_Initialized_Data_Size > 0))
  4985.     {
  4986.       /*
  4987.        *    Do it
  4988.        */
  4989.       Data_Psect = Psect_Number++;
  4990.       VMS_Psect_Spec ("$data",
  4991.               Local_Initialized_Data_Size,
  4992.               "DATA", 0);
  4993.       /*
  4994.        *    Scan the VMS symbols and fill in the data psect
  4995.        */
  4996.       for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
  4997.     {
  4998.       /*
  4999.        *    Only look for undefined psects
  5000.        */
  5001.       if (vsp->Psect_Index < 0)
  5002.         {
  5003.           /*
  5004.            *    And only initialized data
  5005.            */
  5006.           if ((S_GET_TYPE (vsp->Symbol) == N_DATA) && !S_IS_EXTERNAL (vsp->Symbol))
  5007.         vsp->Psect_Index = Data_Psect;
  5008.         }
  5009.     }
  5010.     }
  5011.  
  5012.   /*******  Text Information and Relocation Records  *******/
  5013.   /*
  5014.    *    Write the text segment data
  5015.    */
  5016.   if (text_siz > 0)
  5017.     {
  5018.       /*
  5019.        *    Scan the text fragments
  5020.        */
  5021.       for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
  5022.     {
  5023.       /*
  5024.        *    Stop if we get to the data fragments
  5025.        */
  5026.       if (fragP == data_frag_root)
  5027.         break;
  5028.       /*
  5029.        *    Ignore fragments with no data
  5030.        */
  5031.       if ((fragP->fr_fix == 0) && (fragP->fr_var == 0))
  5032.         continue;
  5033.       /*
  5034.        *    Go the the appropriate offset in the
  5035.        *    Text Psect.
  5036.        */
  5037.       VMS_Set_Psect (Text_Psect, fragP->fr_address, OBJ_S_C_TIR);
  5038.       /*
  5039.        *    Store the "fixed" part
  5040.        */
  5041.       if (fragP->fr_fix)
  5042.         VMS_Store_Immediate_Data (fragP->fr_literal,
  5043.                       fragP->fr_fix,
  5044.                       OBJ_S_C_TIR);
  5045.       /*
  5046.        *    Store the "variable" part
  5047.        */
  5048.       if (fragP->fr_var && fragP->fr_offset)
  5049.         VMS_Store_Repeated_Data (fragP->fr_offset,
  5050.                      fragP->fr_literal +
  5051.                      fragP->fr_fix,
  5052.                      fragP->fr_var,
  5053.                      OBJ_S_C_TIR);
  5054.     }
  5055.       /*
  5056.        *    Now we go through the text segment fixups and
  5057.        *    generate TIR records to fix up addresses within
  5058.        *    the Text Psect
  5059.        */
  5060.       for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
  5061.     {
  5062.       /*
  5063.        *    We DO handle the case of "Symbol - Symbol" as
  5064.        *    long as it is in the same segment.
  5065.        */
  5066.       if (fixP->fx_subsy && fixP->fx_addsy)
  5067.         {
  5068.           int i;
  5069.  
  5070.           /*
  5071.            *    They need to be in the same segment
  5072.            */
  5073.           if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
  5074.           S_GET_RAW_TYPE (fixP->fx_addsy))
  5075.         error ("Fixup data addsy and subsy didn't have the same type");
  5076.           /*
  5077.            *    And they need to be in one that we
  5078.            *    can check the psect on
  5079.            */
  5080.           if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
  5081.           (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
  5082.         error ("Fixup data addsy and subsy didn't have an appropriate type");
  5083.           /*
  5084.            *    This had better not be PC relative!
  5085.            */
  5086.           if (fixP->fx_pcrel)
  5087.         error ("Fixup data was erroneously \"pcrel\"");
  5088.           /*
  5089.            *    Subtract their values to get the
  5090.            *    difference.
  5091.            */
  5092.           i = S_GET_VALUE (fixP->fx_addsy) -
  5093.         S_GET_VALUE (fixP->fx_subsy);
  5094.           /*
  5095.            *    Now generate the fixup object records
  5096.            *    Set the psect and store the data
  5097.            */
  5098.           VMS_Set_Psect (Text_Psect,
  5099.                  fixP->fx_where +
  5100.                  fixP->fx_frag->fr_address,
  5101.                  OBJ_S_C_TIR);
  5102.           VMS_Store_Immediate_Data (&i,
  5103.                     fixP->fx_size,
  5104.                     OBJ_S_C_TIR);
  5105.           /*
  5106.            *    Done
  5107.            */
  5108.           continue;
  5109.         }
  5110.       /*
  5111.        *    Size will HAVE to be "long"
  5112.        */
  5113.       if (fixP->fx_size != sizeof (long))
  5114.         error ("Fixup datum was not a longword");
  5115.       /*
  5116.        *    Symbol must be "added" (if it is ever
  5117.        *                subtracted we can
  5118.        *                fix this assumption)
  5119.        */
  5120.       if (fixP->fx_addsy == 0)
  5121.         error ("Fixup datum was not \"fixP->fx_addsy\"");
  5122.       /*
  5123.        *    Store the symbol value in a PIC fashion
  5124.        */
  5125.       VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy,
  5126.                       fixP->fx_offset,
  5127.                       fixP->fx_pcrel,
  5128.                       Text_Psect,
  5129.                       fixP->fx_where +
  5130.                       fixP->fx_frag->fr_address,
  5131.                       OBJ_S_C_TIR);
  5132.       /*
  5133.        *    Check for indirect address reference,
  5134.        *    which has to be fixed up (as the linker
  5135.        *    will screw it up with TIR_S_C_STO_PICR).
  5136.        */
  5137.       if (fixP->fx_pcrel)
  5138.         VMS_Fix_Indirect_Reference (Text_Psect,
  5139.                     fixP->fx_where +
  5140.                     fixP->fx_frag->fr_address,
  5141.                     fixP->fx_frag,
  5142.                     text_frag_root);
  5143.     }
  5144.     }
  5145.   /*
  5146.    *    Store the Data segment:
  5147.    *
  5148.    *    Since this is REALLY hard to do any other way,
  5149.    *    we actually manufacture the data segment and
  5150.    *    the store the appropriate values out of it.
  5151.    *    The segment was manufactured before, now we just
  5152.    *    dump it into the appropriate psects.
  5153.    */
  5154.   if (data_siz > 0)
  5155.     {
  5156.  
  5157.       /*
  5158.        *    Now we can run through all the data symbols
  5159.        *    and store the data
  5160.        */
  5161.       for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
  5162.     {
  5163.       /*
  5164.        *    Ignore anything other than data symbols
  5165.        */
  5166.       if (S_GET_TYPE (vsp->Symbol) != N_DATA)
  5167.         continue;
  5168.       /*
  5169.        *    Set the Psect + Offset
  5170.        */
  5171.       VMS_Set_Psect (vsp->Psect_Index,
  5172.              vsp->Psect_Offset,
  5173.              OBJ_S_C_TIR);
  5174.       /*
  5175.        *    Store the data
  5176.        */
  5177.       VMS_Store_Immediate_Data (Data_Segment +
  5178.                     S_GET_VALUE (vsp->Symbol) -
  5179.                     text_siz,
  5180.                     vsp->Size,
  5181.                     OBJ_S_C_TIR);
  5182.     }
  5183.       /*
  5184.        *    Now we go through the data segment fixups and
  5185.        *    generate TIR records to fix up addresses within
  5186.        *    the Data Psects
  5187.        */
  5188.       for (fixP = data_fix_root; fixP; fixP = fixP->fx_next)
  5189.     {
  5190.       /*
  5191.        *    Find the symbol for the containing datum
  5192.        */
  5193.       for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
  5194.         {
  5195.           /*
  5196.            *    Only bother with Data symbols
  5197.            */
  5198.           sp = vsp->Symbol;
  5199.           if (S_GET_TYPE (sp) != N_DATA)
  5200.         continue;
  5201.           /*
  5202.            *    Ignore symbol if After fixup
  5203.            */
  5204.           if (S_GET_VALUE (sp) >
  5205.           (fixP->fx_where +
  5206.            fixP->fx_frag->fr_address))
  5207.         continue;
  5208.           /*
  5209.            *    See if the datum is here
  5210.            */
  5211.           if ((S_GET_VALUE (sp) + vsp->Size) <=
  5212.           (fixP->fx_where +
  5213.            fixP->fx_frag->fr_address))
  5214.         continue;
  5215.           /*
  5216.            *    We DO handle the case of "Symbol - Symbol" as
  5217.            *    long as it is in the same segment.
  5218.            */
  5219.           if (fixP->fx_subsy && fixP->fx_addsy)
  5220.         {
  5221.           int i;
  5222.  
  5223.           /*
  5224.            *    They need to be in the same segment
  5225.            */
  5226.           if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
  5227.               S_GET_RAW_TYPE (fixP->fx_addsy))
  5228.             error ("Fixup data addsy and subsy didn't have the same type");
  5229.           /*
  5230.            *    And they need to be in one that we
  5231.            *    can check the psect on
  5232.            */
  5233.           if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
  5234.               (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
  5235.             error ("Fixup data addsy and subsy didn't have an appropriate type");
  5236.           /*
  5237.            *    This had better not be PC relative!
  5238.            */
  5239.           if (fixP->fx_pcrel)
  5240.             error ("Fixup data was erroneously \"pcrel\"");
  5241.           /*
  5242.            *    Subtract their values to get the
  5243.            *    difference.
  5244.            */
  5245.           i = S_GET_VALUE (fixP->fx_addsy) -
  5246.             S_GET_VALUE (fixP->fx_subsy);
  5247.           /*
  5248.            *    Now generate the fixup object records
  5249.            *    Set the psect and store the data
  5250.            */
  5251.           VMS_Set_Psect (vsp->Psect_Index,
  5252.                  fixP->fx_frag->fr_address +
  5253.                  fixP->fx_where -
  5254.                  S_GET_VALUE (vsp->Symbol) +
  5255.                  vsp->Psect_Offset,
  5256.                  OBJ_S_C_TIR);
  5257.           VMS_Store_Immediate_Data (&i,
  5258.                         fixP->fx_size,
  5259.                         OBJ_S_C_TIR);
  5260.           /*
  5261.            *    Done
  5262.            */
  5263.           break;
  5264.         }
  5265.           /*
  5266.            *    Size will HAVE to be "long"
  5267.            */
  5268.           if (fixP->fx_size != sizeof (long))
  5269.         error ("Fixup datum was not a longword");
  5270.           /*
  5271.            *    Symbol must be "added" (if it is ever
  5272.            *                subtracted we can
  5273.            *                fix this assumption)
  5274.            */
  5275.           if (fixP->fx_addsy == 0)
  5276.         error ("Fixup datum was not \"fixP->fx_addsy\"");
  5277.           /*
  5278.            *    Store the symbol value in a PIC fashion
  5279.            */
  5280.           VMS_Store_PIC_Symbol_Reference (
  5281.                            fixP->fx_addsy,
  5282.                            fixP->fx_offset,
  5283.                            fixP->fx_pcrel,
  5284.                            vsp->Psect_Index,
  5285.                            fixP->fx_frag->fr_address +
  5286.                            fixP->fx_where -
  5287.                            S_GET_VALUE (vsp->Symbol) +
  5288.                            vsp->Psect_Offset,
  5289.                            OBJ_S_C_TIR);
  5290.           /*
  5291.            *    Done
  5292.            */
  5293.           break;
  5294.         }
  5295.  
  5296.     }
  5297.     }
  5298.  
  5299.   /*
  5300.    *    Write the Traceback Begin Module record
  5301.    */
  5302.   VMS_TBT_Module_Begin ();
  5303.   /*
  5304.    *    Scan the symbols and write out the routines
  5305.    *    (this makes the assumption that symbols are in
  5306.    *     order of ascending text segment offset)
  5307.    */
  5308.   {
  5309.     struct symbol *Current_Routine = 0;
  5310.     int Current_Line_Number = 0;
  5311.     int Current_Offset = -1;
  5312.     struct input_file *Current_File;
  5313.  
  5314. /* Output debugging info for global variables and static variables that are not
  5315.  * specific to one routine. We also need to examine all stabs directives, to
  5316.  * find the definitions to all of the advanced data types, and this is done by
  5317.  * VMS_LSYM_Parse.  This needs to be done before any definitions are output to
  5318.  * the object file, since there can be forward references in the stabs
  5319.  * directives. When through with parsing, the text of the stabs directive
  5320.  * is altered, with the definitions removed, so that later passes will see
  5321.  * directives as they would be written if the type were already defined.
  5322.  *
  5323.  * We also look for files and include files, and make a list of them.  We
  5324.  * examine the source file numbers to establish the actual lines that code was
  5325.  * generated from, and then generate offsets.
  5326.  */
  5327.     VMS_LSYM_Parse ();
  5328.     for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  5329.       {
  5330.     /*
  5331.      *    Deal with STAB symbols
  5332.      */
  5333.     if (S_IS_DEBUG (symbolP))
  5334.       {
  5335.         /*
  5336.          *    Dispatch on STAB type
  5337.          */
  5338.         switch ((unsigned char) S_GET_RAW_TYPE (symbolP))
  5339.           {
  5340.           case N_SLINE:
  5341.         if (S_GET_DESC (symbolP) > Current_File->max_line)
  5342.           Current_File->max_line = S_GET_DESC (symbolP);
  5343.         if (S_GET_DESC (symbolP) < Current_File->min_line)
  5344.           Current_File->min_line = S_GET_DESC (symbolP);
  5345.         break;
  5346.           case N_SO:
  5347.         Current_File = find_file (symbolP);
  5348.         Current_File->flag = 1;
  5349.         Current_File->min_line = 1;
  5350.         break;
  5351.           case N_SOL:
  5352.         Current_File = find_file (symbolP);
  5353.         break;
  5354.           case N_GSYM:
  5355.         VMS_GSYM_Parse (symbolP, Text_Psect);
  5356.         break;
  5357.           case N_LCSYM:
  5358.         VMS_LCSYM_Parse (symbolP, Text_Psect);
  5359.         break;
  5360.           case N_FUN:    /* For static constant symbols */
  5361.           case N_STSYM:
  5362.         VMS_STSYM_Parse (symbolP, Text_Psect);
  5363.         break;
  5364.           }
  5365.       }
  5366.       }
  5367.  
  5368.     /* now we take a quick sweep through the files and assign offsets
  5369.     to each one.  This will essentially be the starting line number to the
  5370.    debugger for each file.  Output the info for the debugger to specify the
  5371.    files, and then tell it how many lines to use */
  5372.     {
  5373.       int File_Number = 0;
  5374.       int Debugger_Offset = 0;
  5375.       int file_available;
  5376.       Current_File = file_root;
  5377.       for (Current_File = file_root; Current_File; Current_File = Current_File->next)
  5378.     {
  5379.       if (Current_File == (struct input_file *) NULL)
  5380.         break;
  5381.       if (Current_File->max_line == 0)
  5382.         continue;
  5383.       if ((strncmp (Current_File->name, "GNU_GXX_INCLUDE:", 16) == 0) &&
  5384.           !flag_debug)
  5385.         continue;
  5386.       if ((strncmp (Current_File->name, "GNU_CC_INCLUDE:", 15) == 0) &&
  5387.           !flag_debug)
  5388.         continue;
  5389. /* show a few extra lines at the start of the region selected */
  5390.       if (Current_File->min_line > 2)
  5391.         Current_File->min_line -= 2;
  5392.       Current_File->offset = Debugger_Offset - Current_File->min_line + 1;
  5393.       Debugger_Offset += Current_File->max_line - Current_File->min_line + 1;
  5394.       if (Current_File->same_file_fpnt != (struct input_file *) NULL)
  5395.         Current_File->file_number = Current_File->same_file_fpnt->file_number;
  5396.       else
  5397.         {
  5398.           Current_File->file_number = ++File_Number;
  5399.           file_available = VMS_TBT_Source_File (Current_File->name,
  5400.                          Current_File->file_number);
  5401.           if (!file_available)
  5402.         {
  5403.           Current_File->file_number = 0;
  5404.           File_Number--;
  5405.           continue;
  5406.         }
  5407.         }
  5408.       VMS_TBT_Source_Lines (Current_File->file_number,
  5409.                 Current_File->min_line,
  5410.                Current_File->max_line - Current_File->min_line + 1);
  5411.     }            /* for */
  5412.     }                /* scope */
  5413.     Current_File = (struct input_file *) NULL;
  5414.  
  5415.     for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  5416.       {
  5417.     /*
  5418.      *    Deal with text symbols
  5419.      */
  5420.     if (!S_IS_DEBUG (symbolP) && (S_GET_TYPE (symbolP) == N_TEXT))
  5421.       {
  5422.         /*
  5423.          *    Ignore symbols starting with "L",
  5424.          *    as they are local symbols
  5425.          */
  5426.         if (*S_GET_NAME (symbolP) == 'L')
  5427.           continue;
  5428.         /*
  5429.          *    If there is a routine start defined,
  5430.          *    terminate it.
  5431.          */
  5432.         if (Current_Routine)
  5433.           {
  5434.         /*
  5435.          *    End the routine
  5436.          */
  5437.         VMS_TBT_Routine_End (text_siz, Current_Routine);
  5438.           }
  5439.         /*
  5440.          *    Check for & skip dummy labels like "gcc_compiled.".
  5441.          *    They're identified by the IN_DEFAULT_SECTION flag.
  5442.          */
  5443.         if ((S_GET_OTHER (symbolP) & IN_DEFAULT_SECTION) != 0 &&
  5444.               (S_GET_VALUE (symbolP) == 0))
  5445.           continue;
  5446.         /*
  5447.          *    Store the routine begin traceback info
  5448.          */
  5449.         if (Text_Psect != -1)
  5450.           {
  5451.         VMS_TBT_Routine_Begin (symbolP, Text_Psect);
  5452.         Current_Routine = symbolP;
  5453.           }
  5454. /* Output local symbols, i.e. all symbols that are associated with a specific
  5455.  * routine.  We output them now so the debugger recognizes them as local to
  5456.  * this routine.
  5457.  */
  5458.         {
  5459.           symbolS *symbolP1;
  5460.           char *pnt;
  5461.           char *pnt1;
  5462.           for (symbolP1 = Current_Routine; symbolP1; symbolP1 = symbol_next (symbolP1))
  5463.         {
  5464.           if (!S_IS_DEBUG (symbolP1))
  5465.             continue;
  5466.           if (S_GET_RAW_TYPE (symbolP1) != N_FUN)
  5467.             continue;
  5468.           pnt = S_GET_NAME (symbolP);
  5469.           pnt1 = S_GET_NAME (symbolP1);
  5470.           if (*pnt++ != '_')
  5471.             continue;
  5472.           while (*pnt++ == *pnt1++)
  5473.             {
  5474.             }
  5475.           if (*pnt1 != 'F' && *pnt1 != 'f') continue;
  5476.           if ((*(--pnt) == '\0') && (*(--pnt1) == ':'))
  5477.             break;
  5478.         }
  5479.           if (symbolP1 != (symbolS *) NULL)
  5480.         VMS_DBG_Define_Routine (symbolP1, Current_Routine, Text_Psect);
  5481.         }            /* local symbol block */
  5482.         /*
  5483.          *    Done
  5484.          */
  5485.         continue;
  5486.       }
  5487.     /*
  5488.      *    Deal with STAB symbols
  5489.      */
  5490.     if (S_IS_DEBUG (symbolP))
  5491.       {
  5492.         /*
  5493.          *    Dispatch on STAB type
  5494.          */
  5495.         switch ((unsigned char) S_GET_RAW_TYPE (symbolP))
  5496.           {
  5497.         /*
  5498.          *    Line number
  5499.          */
  5500.           case N_SLINE:
  5501.         /* Offset the line into the correct portion
  5502.          * of the file */
  5503.         if (Current_File->file_number == 0)
  5504.           break;
  5505.         /* Sometimes the same offset gets several source
  5506.          * lines assigned to it.
  5507.          * We should be selective about which lines
  5508.          * we allow, we should prefer lines that are
  5509.          * in the main source file when debugging
  5510.          * inline functions. */
  5511.         if ((Current_File->file_number != 1) &&
  5512.             S_GET_VALUE (symbolP) ==
  5513.             Current_Offset)
  5514.           break;
  5515.         /* calculate actual debugger source line */
  5516.         S_GET_DESC (symbolP)
  5517.           += Current_File->offset;
  5518.         /*
  5519.          *    If this is the 1st N_SLINE, setup
  5520.          *    PC/Line correlation.  Otherwise
  5521.          *    do the delta PC/Line.  If the offset
  5522.          *    for the line number is not +ve we need
  5523.          *    to do another PC/Line correlation
  5524.          *    setup
  5525.          */
  5526.         if (Current_Offset == -1)
  5527.           {
  5528.             VMS_TBT_Line_PC_Correlation (
  5529.                           S_GET_DESC (symbolP),
  5530.                           S_GET_VALUE (symbolP),
  5531.                           Text_Psect,
  5532.                           0);
  5533.           }
  5534.         else
  5535.           {
  5536.             if ((S_GET_DESC (symbolP) -
  5537.              Current_Line_Number) <= 0)
  5538.               {
  5539.             /*
  5540.              *    Line delta is not +ve, we
  5541.              *    need to close the line and
  5542.              *    start a new PC/Line
  5543.              *    correlation.
  5544.              */
  5545.             VMS_TBT_Line_PC_Correlation (0,
  5546.                              S_GET_VALUE (symbolP) -
  5547.                              Current_Offset,
  5548.                              0,
  5549.                              -1);
  5550.             VMS_TBT_Line_PC_Correlation (
  5551.                               S_GET_DESC (symbolP),
  5552.                               S_GET_VALUE (symbolP),
  5553.                               Text_Psect,
  5554.                               0);
  5555.               }
  5556.             else
  5557.               {
  5558.             /*
  5559.              *    Line delta is +ve, all is well
  5560.              */
  5561.             VMS_TBT_Line_PC_Correlation (
  5562.                               S_GET_DESC (symbolP) -
  5563.                               Current_Line_Number,
  5564.                               S_GET_VALUE (symbolP) -
  5565.                               Current_Offset,
  5566.                               0,
  5567.                               1);
  5568.               }
  5569.           }
  5570.         /*
  5571.          *    Update the current line/PC
  5572.          */
  5573.         Current_Line_Number = S_GET_DESC (symbolP);
  5574.         Current_Offset = S_GET_VALUE (symbolP);
  5575.         /*
  5576.          *    Done
  5577.          */
  5578.         break;
  5579.         /*
  5580.          *    Source file
  5581.          */
  5582.           case N_SO:
  5583.         /*
  5584.          *    Remember that we had a source file
  5585.          *    and emit the source file debugger
  5586.          *    record
  5587.          */
  5588.         Current_File =
  5589.           find_file (symbolP);
  5590.         break;
  5591. /* We need to make sure that we are really in the actual source file when
  5592.  * we compute the maximum line number.  Otherwise the debugger gets really
  5593.  * confused */
  5594.           case N_SOL:
  5595.         Current_File =
  5596.           find_file (symbolP);
  5597.         break;
  5598.           }
  5599.       }
  5600.       }
  5601.     /*
  5602.      *    If there is a routine start defined,
  5603.      *    terminate it (and the line numbers)
  5604.      */
  5605.     if (Current_Routine)
  5606.       {
  5607.     /*
  5608.      *    Terminate the line numbers
  5609.      */
  5610.     VMS_TBT_Line_PC_Correlation (0,
  5611.                    text_siz - S_GET_VALUE (Current_Routine),
  5612.                      0,
  5613.                      -1);
  5614.     /*
  5615.      *    Terminate the routine
  5616.      */
  5617.     VMS_TBT_Routine_End (text_siz, Current_Routine);
  5618.       }
  5619.   }
  5620.   /*
  5621.    *    Write the Traceback End Module TBT record
  5622.    */
  5623.   VMS_TBT_Module_End ();
  5624.  
  5625.   /*
  5626.    *    Write the End Of Module record
  5627.    */
  5628.   if (Entry_Point_Symbol == 0)
  5629.     Write_VMS_EOM_Record (-1, 0);
  5630.   else
  5631.     Write_VMS_EOM_Record (Text_Psect,
  5632.               S_GET_VALUE (Entry_Point_Symbol));
  5633.  
  5634.   /*
  5635.    *    All done, close the object file
  5636.    */
  5637.   Close_VMS_Object_File ();
  5638. }
  5639.  
  5640. /* end of obj-vms.c */
  5641.